К основному содержанию
скилл CX Codex

building-apis — скилл для Claude Code: Celigo API из запроса

Скилл объясняет агенту, как собрать HTTP-эндпоинт в Celigo: внешняя система шлёт запрос, интеграция обрабатывает его и возвращает структурированный ответ.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add celigo/ai --skill building-apis -a claude-code
Открыть на GitHub

Что делает building-apis

Скилл описывает API в Celigo как REST-эндпоинт, который отдаёт наружу логику интеграции. Внешний вызывающий приходит по HTTP, запрос проходит через лукапы и импорты, а обратно уходит готовый ответ. Агент получает карту того, из чего такой эндпоинт состоит: выбор режима, описание запроса, конвейер обработки, маршрутизация и формирование ответа.

Режимов два. В builder-режиме всё собирается визуально: request с методом и относительным путём, routers[] с ветками и фильтрами, responseRouter и набор responses[] со статус-кодами и маппингами. В script-режиме работает одна функция handleRequest, которая получает метод, заголовки без Authorization, queryString, body и rawBody и возвращает {statusCode, headers, body}. У скриптового режима нет pathParams и queryParams — это повод выбрать builder, если путь и query-параметры нужны в обработке.

Отдельный момент, который легко упустить: у API нет собственного источника данных. Тело запроса и есть запись, поэтому path-параметры, query-параметры и заголовки попадают дальше только через transform запроса. Своего расписания у API тоже нет, повтор после сбоя — решение вызывающей стороны. Аутентификация не своя: вызывающий присылает токен Celigo с полным доступом или ограниченный областью _apiIds. Верхнеуровневый disabled: true снимает API с публикации, и вызывающие получают 404, пока его не включат обратно.

Какие задачи решает

  • открыть наружу операцию поиска или записи как REST-эндпоинт
  • проксировать запрос к внешней системе через аутентифицированное соединение
  • вернуть вызывающей стороне разные ответы в зависимости от успеха или ошибки
  • протащить данные из ответа одного процессора в следующий шаг конвейера
  • выбрать между визуальной сборкой и полным контролем на JavaScript

Примеры запросов агенту

  • Собери Celigo API в builder-режиме: POST-эндпоинт, который принимает заказ и возвращает его id
  • Опиши script-режим API с функцией handleRequest и своей проверкой заголовков
  • Настрой responseRouter так, чтобы ошибки импорта уходили в отдельный ответ со своим статус-кодом

Как установить building-apis

1Через Skills CLI (Vercel)

npx skills add celigo/ai --skill building-apis -a claude-code

2Вручную: положить файлы

~/.claude/skills/building-apis/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/building-apis/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о building-apis

Как установить building-apis в Claude?

Выполните npx skills add celigo/ai --skill building-apis -a claude-code. После этого файл скилла лежит в ~/.claude/skills/building-apis/SKILL.md.

Что делает скилл building-apis?

Он даёт агенту схему сборки Celigo API: режимы builder и script, описание запроса, конвейер из роутеров и page-процессоров, маршрутизация и формирование ответа.

Чем script-режим отличается от builder?

В script-режиме вся логика в одной функции handleRequest, и pathParams с queryParams ей не передаются. Builder даёт визуальную конфигурацию и работает с этими параметрами через transform запроса.

Исходный текст

SKILL.md · MIT
---
name: building-apis
description: Build Celigo APIs -- custom HTTP endpoints that let external systems push or query data synchronously through Celigo integrations. Use when creating APIs, proxying authenticated requests, exposing lookup/write operations as a REST interface that returns a structured response, or publishing an API to API Management.
---

<!-- TIER:1 -->

# Building APIs

An API is a **RESTful endpoint** that exposes integration logic for external consumption. External systems call the API over HTTP; the API processes the request through lookups and imports, then returns a structured response. Concerns when building an API:

- **Mode selection** -- builder (visual configuration) vs script (full JavaScript control)
- **Request definition** -- HTTP method, URI path, parameters, body schema, request transformation
- **Processing pipeline** -- routers and page processors (lookups + imports) that execute business logic
- **Response routing** -- directing processed data to the correct response definition based on success/failure or custom conditions
- **Response shaping** -- status codes, field mappings, body schema, hooks (preMap, postMap) on each response
- **Response mapping** -- extracting fields from each page processor's response back into the record for downstream steps. Configured on each `pageProcessors[]` entry, same as in flows. For lookup exports the response has `data[]` and `errors[]` (use `data[0].fieldName` for single results). For imports use `id` for the created record's ID and `_json.fieldName` for response-body fields
- **postResponseMap hook** -- JavaScript processing after response mapping, configured on `pageProcessors[]` entries

Used across integrations alongside flows and tools. APIs do not have their own authentication -- callers send a Celigo API token with full access or one scoped to the API (`_apiIds`; see [managing-api-tokens > Access Scope Decision Matrix](../managing-api-tokens/SKILL.md#access-scope-decision-matrix)) to `https://api.integrator.io/apis/{version}{relativeURI}`; outbound calls to external systems use the connections referenced by exports/imports in the pipeline.

## The Request IS the Source Record

APIs are invoked by an external HTTP caller -- there is no upstream export, no scheduler, no listener feeding them. That has three design consequences:

- **The request body is the input shape.** What the caller sends in the body is what downstream processing sees as the record. Path params, query params and headers aren't on `record`: only the ones the request declares reach the request `transform` (as `{{pathParams.<key>}}`, `{{queryParams.<key>}}` and `{{headers.<key>}}`), and later steps see only what the transform writes onto the record. There is no upstream pipeline to reshape the body first -- use the request `transform` if it needs reshaping before routing.
- **The response stage is the output.** Whatever the selected response definition produces is exactly what the caller receives. Nothing runs after it.
- **No self-starting.** APIs have no `schedule`, no listener, and none of the flow-level runtime controls (`skipRetries`, chaining). "Every night at 2 AM, do X" is a flow -- possibly one that *calls* the API, but the schedule lives on the flow. Retry-after-failure is the caller's decision. A page processor's `proceedOnFailure` does apply (see [Response selection](#response-selection----success-fail-custom)).

When a flow needs to invoke an API, it does so as an ordinary HTTP caller (an HTTP export/import pointing at the API's URL). There is no special flow-step-to-API wiring.

A top-level `disabled: true` takes the API offline without deleting it -- callers get a 404 until it's re-enabled.

## API Modes

### Builder Mode (`type: "builder"`)

Visual configuration with discrete components:

```
API (type: "builder")
+-- request            -- method, relativeURI, params, bodySchema, mockRequest, transform
+-- routers[]          -- optional processing pipeline (same structure as flow routers)
|   +-- branches[]
|       +-- inputFilter        -- when to use this branch (s-expression rules)
|       +-- pageProcessors[]   -- lookups (exports) and imports
|       +-- nextRouterId       -- chain to next router, or "apiRouter" to finish
+-- responseRouter     -- id="apiRouter", routes processed data to a response
+-- responses[]        -- success, fail, custom -- each with statusCode, inputFilter, mappings
```

The incoming HTTP request **replaces the export** as data source. Routers and page processors work identically to flows.

#### API Execution Pipeline (Builder Mode)

When an API receives a request:

1. **Request received** -- method + path matched against the API endpoint definition
2. **Request transform** (optional) -- reshapes the incoming request body before routing
3. **Router evaluation** -- `routeRecordsUsing` evaluates branch input filter conditions
4. **Branch selection** -- first matching branch processes the request
5. **Page processors** -- each processor in the branch executes sequentially (export lookups, import writes)
6. **Response mapping** -- `responseMapping` on each processor carries data forward to the next processor
7. **Response router** -- `responseRouter` (id="apiRouter") selects which response template to use based on response input filters
8. **Response** -- selected response template returned to the caller with its statusCode, headers, and body

### Script Mode (`type: "script"`)

A single JavaScript function (`handleRequest`) gets `options.method`, `headers` (without `Authorization`), `queryString`, `body` and `rawBody` -- no `pathParams` or `queryParams` -- and returns `{statusCode, headers, body}` ([writing-scripts > Routing and Handlers](../writing-scripts/SKILL.md#routing-and-handlers)). Callers reach it at `/v1/apis/<_id>/request`. Complete control with no visual configuration.

**Legacy script APIs**, made before builder mode, can still turn up in an account: they have no `type`, `version`, `disabled` or `builder`, only the top-level `_scriptId` and `function` that script-mode APIs also carry as read-only copies. If `type` is absent and `_scriptId` is present, it's legacy. You can't create one: a create without `type` makes a script-mode API (422 "Script type apis must have valid scriptId and function." when it has no `script`), and the mode can't be changed later.

## Quick Reference

### Decision Matrix

| Scenario | Mode | Why |
|----------|------|-----|
| Standard lookup/write with structured response | Builder | Visual debugging, test runs, structured responses |
| Multiple response shapes based on success/failure | Builder | Response router + inputFilter handles this declaratively |
| Complex conditional logic or custom auth validation | Script | Full JavaScript control over request/response |
| Dynamic routing that can't be expressed as input filters | Script | `handleRequest` can implement arbitrary logic |
| Proxy through an authenticated connection | Builder | Wire the connection's export/import as a page processor |
| Simple webhook receiver that transforms and forwards | Builder | Single router, single branch, one import |

### Minimum Required Fields

| Mode | Required Fields |
|------|----------------|
| Builder | `name`, `type: "builder"`, `builder.request` (method + relativeURI) |
| Script | `name`, `type: "script"`, `script._scriptId`, `script.function` |

### Schema Index

All schemas are in [references/schemas/](references/schemas/):

| Schema | What it defines |
|--------|----------------|
| [request.yml](references/schemas/request.yml) | Top-level API fields (name, type, version, disabled, builder/script refs) |
| [response.yml](references/schemas/response.yml) | API response shape |
| [builder.yml](references/schemas/builder.yml) | Builder configuration (request, routers, responseRouter, responses refs) |
| [api-request.yml](references/schemas/api-request.yml) | Request config (method, relativeURI, params, bodySchema, mockRequest, transform) |
| [api-response.yml](references/schemas/api-response.yml) | Response definitions (id, name, type, statusCode, inputFilter, mappings, hooks) |
| [response-router.yml](references/schemas/response-router.yml) | Response router (id="apiRouter", routeRecordsUsing) |
| [router.yml](references/schemas/router.yml) | Routers (branches, inputFilter, pageProcessors) |
| [script.yml](references/schemas/script.yml) | Script config (_scriptId, function) |
| [apim.yml](references/schemas/apim.yml) | APIM metadata (publication status) |
| [shipworks.yml](references/schemas/shipworks.yml) | Legacy ShipWorks auth |

## Related Skills

- [configuring-exports > Quick Reference](../configuring-exports/SKILL.md#quick-reference) -- building lookup exports used as page processors in the API pipeline
- [configuring-imports > Quick Reference](../configuring-imports/SKILL.md#quick-reference) -- building imports used as page processors in the API pipeline
- [building-flows > How to Build a Flow](../building-flows/SKILL.md#how-to-build-a-flow) -- flows share the same router/branch/pageProcessor pipeline mechanics
- [writing-scripts > Quick Reference](../writing-scripts/SKILL.md#quick-reference) -- writing `handleRequest` (script-mode APIs), `preMap`/`postMap` hooks, and `postResponseMap`
- [writing-handlebars > Quick Reference](../writing-handlebars/SKILL.md#quick-reference) -- dynamic expressions in request bodies, URIs, and response mappings
- [configuring-filters > Quick Reference](../configuring-filters/SKILL.md#quick-reference) -- input filters on router branches to conditionally route records

<!-- TIER:2 -->

## How to Build an API

### 1. Plan what the API needs to do

Before creating anything, understand the requirements: what endpoint the caller needs, what data it sends, what systems are involved, what the response should look like. This determines everything -- mode, pipeline shape, which connections/exports/imports are needed.

### 2. Decide the mode

Use **builder** for most APIs -- it provides visual debugging, test runs, and structured responses. Use **script** only when the processing logic is too dynamic for the visual pipeline (e.g., complex conditional responses, custom auth validation, dynamic routing).

### 3. Check for existing resources

Look for connections, exports, and imports that can be reused before creating new ones.

```bash
# Search across all resource types in the account
celigo account search "<keyword>"

# Show what an existing API uses -- the local index records no edges out of APIs
celigo apis connections <id>
celigo apis get <id>

# Find orphaned resources that could be reused
celigo account lint

# Search for APIs already in the account for patterns
celigo apis list | grep -i "<keyword>"

# Check existing exports/imports that could serve as pipeline steps
celigo exports list | grep -i "<system-name>"
celigo imports list | grep -i "<system-name>"

# Search marketplace for pre-built integration templates
celigo templates marketplace
```

The account index auto-refreshes when stale (older than 15 minutes by default). Force a fresh snapshot with `celigo account snapshot`.

### 4. Create the supporting resources (bottom-up)

APIs reference exports and imports as page processors -- these must exist before you can attach them. Build order:

1. **Connections** -- create or reuse connections to the target systems
2. **Exports** -- for lookups that query external systems (use `configuring-exports` skill)
3. **Imports** -- for writes to external systems (use `configuring-imports` skill)

### 5. Define the request (builder mode)

Choose the HTTP method (`GET`, `POST`, `PUT`, `PATCH` or `DELETE`; GET and POST are most common) and URI path.

- Path parameters use colon notation: `/customers/:id`
- Declare the query parameters, path parameters and headers the API reads (`queryParams`, `pathParams`, `headers`; header keys in lowercase): only declared ones reach the request `transform`. Add the body schema too (every object node in a `bodySchema` needs properties; Gotcha 11)
- Save a `mockRequest` as a sample request, but send the test request explicitly when you test (step 10)
- Optionally add a request `transform` (expression-based or script-based) to reshape incoming data before processing

### 6. Build the processing pipeline

The pipeline is made of routers, branches, and page processors. See [router.yml](references/schemas/router.yml) for the full schema.

Routers are optional: an API that only reshapes the request can go straight to the response router, with the responses mapping request fields. Once the API calls other systems, add a router -- it's the container that holds branches, and branches hold the page processors that do the actual work. Use multiple branches when different request conditions need different processing paths (e.g., branch by HTTP method, request field value, or record type). Use multiple routers when you need sequential stages of processing where each stage can branch independently.

For pass-through routers (single branch, no filters, just linear steps before a branching router), omit `routeRecordsTo` and `routeRecordsUsing` -- including them makes it appear as a filter-based branch in the UI. Leaving both unset is the pass-through shape; the server fills in no default.

A branch's `inputFilter`, like a response's, is `{"version": "1", "rules": [...]}`, and its `rules` use s-expression syntax: `["operator", ["type", ["extract", "field"]], value]`. Type wrappers (`string`, `number`, `boolean`) are required around `extract` and `context` accessors. Logical combinators: `["and", cond1, cond2]`, `["or", cond1, cond2]`. Don't send the `{"type": "expression", "expression": {...}}` form that export and import filters use (Gotcha 13).

Every branch sets `nextRouterId`: another router's `id`, or `"apiRouter"` to reach the response router. A branch without one saves, but every test run is then refused with 400 "One or more branches are not merged back. Review the setup to ensure all branches converge.", whichever branch the request takes.

### 7. Configure responses

Every builder API needs exactly one `success` response and one `fail` response. Add `custom` responses for specific scenarios (e.g., 404 not found, 422 validation error), and list them before `success`: the first response in `responses[]` whose `inputFilter` matches is the one returned, and a response without an `inputFilter` matches every request.

Each response has:

- `statusCode` (HTTP status code)
- `inputFilter` to determine when it's selected (optional; see [Response selection](#response-selection----success-fail-custom))
- `mappings` to shape the response body from the processed record. The body is a JSON object, so put a list under a property (`{"records": [...]}`)
- Optional `bodySchema` for documentation, `headers`, `lookups`, and `hooks` (preMap, postMap)
- Optional `mockInput` for trying the mappings, in the record-page format `{"page_of_records": [{"record": {...}}]}`; any other object is refused with 422

To return a large lookup result one page per call, see [references/pagination.md](references/pagination.md).

### 8. Configure the response router

Set `id: "apiRouter"` and choose routing method:

- `input_filters` (default) -- evaluates each response's `inputFilter`
- `script` -- custom JavaScript returns the response `id` to use

### 9. Build the JSON

Reference the [Schema Index](#schema-index) above for exact field schemas.

Every API needs at minimum: `name`, `type`, and either `builder` (with `request`) or `script` (with `_scriptId` and `function`).

A complete builder API with one lookup, a 404 for "not found", a nested success body and the fail response. `request`, `routers`, `responseRouter` and `responses` are siblings under `builder`:

```json
{
  "name": "Get item stock",
  "type": "builder",
  "version": "v1",
  "disabled": false,
  "_integrationId": "<integration id>",
  "builder": {
    "request": {"method": "POST", "relativeURI": "/items/stock"},
    "routers": [{
      "id": "lookup_item",
      "branches": [{
        "name": "Look up the item",
        "pageProcessors": [{
          "type": "export",
          "_exportId": "<lookup export id>",
          "responseMapping": {"fields": [{"extract": "data[0]", "generate": "item"}]}
        }],
        "nextRouterId": "apiRouter"
      }]
    }],
    "responseRouter": {"id": "apiRouter", "routeRecordsUsing": "input_filters"},
    "responses": [
      {
        "id": "notFound", "name": "Not found", "type": "custom", "statusCode": 404,
        "inputFilter": {"version": "1", "rules": ["empty", ["string", ["extract", "item.sku"]]]},
        "mappings": [{"generate": "error", "dataType": "string", "hardCodedValue": "Item not found", "status": "Active"}]
      },
      {
        "id": "success", "name": "Success", "type": "success", "statusCode": 200,
        "mappings": [{
          "generate": "item", "dataType": "object", "status": "Active",
          "mappings": [
            {"generate": "sku", "dataType": "string", "extract": "$.item.sku", "status": "Active"},
            {"generate": "onHand", "dataType": "number", "extract": "$.item.onHand", "status": "Active"}
          ]
        }]
      },
      {"id": "fail", "name": "Fail", "type": "fail", "statusCode": 500, "mappings": []}
    ]
  }
}
```

The lookup's first record lands on the record as `item`, the custom 404 comes first so it answers when the lookup found nothing, and `success` (no filter) answers everything else.

### 10. Test the API

Send the test request explicitly as `{"mockRequest": {"body": {...}}}`, in a file passed to `celigo apis test-run <id> --file <path>`. To test with the sample saved on the API, read the API first and send its `builder.request.mockRequest` as that `mockRequest`: a run without one starts from an empty record, and the saved one isn't replayed. The body must be a JSON object: an array is refused with 400 "Mock request body should be a plain object." Only the body becomes the record. A test request's `pathParams`, `queryParams` and `headers` reach the request `transform` the way a real call's do: the keys the request declares, and no others. The run's `metadata` names the response it selected: `success`, `fail` or a custom response's `id` is one of its keys.

A lookup export without a saved `mockOutput` calls its live system in a test run, and the run then saves that response on the export as its `mockOutput`. Every later test run that uses the export -- from any API or Tool, whatever the request -- answers the lookup from that saved `mockOutput` instead of calling the system; real calls aren't affected. So when test runs keep returning the same lookup result for different requests, read the export's `mockOutput`, and remove it to test against live data again. Imports never send in a test run: each returns its saved `mockResponse` or a placeholder ([configuring-imports > Testing an Import Without Writing](../configuring-imports/SKILL.md#testing-an-import-without-writing)). So a passing run proves the request shaping and routing but not the writes, and it never shows up in request history. Only a real call to the endpoint does.

## The Response and Routing Model

Once the routers finish processing, the API selects which response to return and shapes its body. This is where APIs diverge most from flows -- the routing is narrower, and "mapping" happens at two distinct layers.

### Branch selection and router chaining

APIs support a single routing strategy: `first_matching_branch`. Within a router, each record is evaluated against the branches in order and taken by the *first* branch whose `inputFilter` matches; that record then follows only that branch. (Flows also offer `all_matching_branches`, which fans one record out to every matching branch -- APIs never do this. A record takes exactly one branch per router.)

Each branch's `nextRouterId` decides where the record goes after that branch's page processors finish:

- **Another router's `id`** -- chain into that router for a further stage of processing.
- **`"apiRouter"`** -- hand off to the response router (whose reserved `id` is always `apiRouter`) to finish.

Chaining lets you express sequential stages where each stage branches independently; every branch ends at another router or at `"apiRouter"`, the response router. An id that names no router fails the save with 422 "Invalid nextRouterId is defined on the branch. Please correct the branch configuration."

### Response selection -- success, fail, custom

Every builder API has exactly one `success` response, exactly one `fail` response, and zero or more `custom` responses (the response's `type` field). The response router (`id: "apiRouter"`) picks one after processing completes:

- **`success`** -- the happy path. It isn't a fallback checked after the `custom` responses: like any response, it's returned when it's the first in the list whose `inputFilter` matches. Conventionally a 2xx `statusCode` (`200`, or `201` when the API created something).
- **`fail`** -- the error path. A step that fails (a lookup returned a 500, an import got a 4xx, a script threw) stops the request, which gets the `fail` response. Set `proceedOnFailure: true` on a page processor to let the next step run after it fails instead; the request can then still end in `success`, because `context.success` stays true. Conventionally a 4xx/5xx `statusCode` (`400` or `500`); its `mappings` surface the error message and any context the caller needs.
- **`custom`** -- a non-error, non-default response selected by its own `inputFilter`. Reach for one when the outcome fits neither `success` nor `fail`, when the `statusCode` differs, or when the body shape differs. Typical cases:
  - **`404` not found** -- the lookup ran but returned zero records (filter: the results array is empty).
  - **`409` conflict** -- the destination rejected a create because the record already exists.
  - **`202` accepted** -- processing started a background job; tell the caller "received, working on it."
  - **Conditional body** -- a different shape driven by a query parameter (e.g. `?format=summary` vs `?format=full`).

In `input_filters` mode the response router returns the first response, in list order, whose `inputFilter` matches, and a response without an `inputFilter` matches every request. So list `custom` responses ahead of `success`. A `success` listed first answers every request that didn't fail, even one a later custom filter matches, and giving it the typed filter `["equals", ["boolean", ["context", "success"]], true]` doesn't change that: `context.success` is true whenever no step failed, including when a lookup found nothing. In `script` mode a JavaScript function inspects the record and returns the response `id` to use.

### `statusCode` vs the response `type`

These are independent and often conflated:

- The response **`type`** (`success` / `fail` / `custom`) is Celigo's internal classification -- it drives which response the response router selects.
- The **`statusCode`** is the HTTP status the caller receives -- it lives on the response definition.

A `custom` response can carry any `statusCode` (the "not found" response returns `404`; the "async accepted" response returns `202`), and `success` is conventionally 2xx but doesn't have to be. So "return a `404` when the customer isn't found" means adding a `custom` response with `statusCode: 404` and an `inputFilter` that matches when the lookup's results array is empty -- not editing the `success` response.

### The two mapping layers

"Mapping" refers to two different things at two layers, and conflating them is the most common source of confusion when building APIs.

**1. Page-processor `responseMapping` (record enrichment).** Configured on a lookup or import inside a router branch -- the same shape as a flow's page-processor `responseMapping`. It pulls fields off that page processor's response and merges them onto the record so downstream routers, page processors, and response mappings can see them. It does **not** shape the HTTP body.

```
{
  "fields": [
    {"extract": "data[0].id", "generate": "customerId"},
    {"extract": "data[0].accountStatus", "generate": "status"}
  ]
}
```

**2. Response-stage `mappings` (HTTP body).** Configured on a `success` / `fail` / `custom` response (alongside its `lookups` and `hooks`). It reads the now-enriched record and builds the HTTP response body returned to the caller.

```
{
  "mappings": [
    {
      "generate": "data",
      "dataType": "object",
      "status": "Active",
      "mappings": [
        {"extract": "$.customerId", "generate": "id", "dataType": "string", "status": "Active"},
        {"extract": "$.status", "generate": "status", "dataType": "string", "status": "Active"}
      ]
    }
  ]
}
```

Response mappings are Mapper 2.0 rows. Every row needs `dataType` and `status` -- a save without `dataType` fails with 422 `Path 'dataType' is required`, once per row that omits it, and a row without `status` fails with 422 `Mapping object must have status field present.` An `extract` reads a field only as a `$.` path or Handlebars: a bare string, `record.customerId` included, is written into the body as that literal text. A dotted `generate` such as `data.id` makes one key with a dot in its name, so build nested objects as an `object` row with child `mappings`, as above. A literal goes in `hardCodedValue` (capital C): a row keyed `hardcodedValue` saves without its value and writes nothing.

The two work together: the lookup's `responseMapping` merges `customerId` onto the record, then the response's `mappings` place `customerId` into the body's `data.id`. A field the page processor returned must first be carried onto the record by a `responseMapping` before a response `mapping` can extract it. When unsure which layer you need, ask: does this step *add* the field to the record (page-processor `responseMapping`) or *read* the field off the record into the body (response `mappings`)?

## Observing Calls

Look for an API's calls in its request history, the run index (`celigo apis request-history <id>`; builder-mode APIs only). It covers the last 5 minutes unless you pass a window (`--time-gte`, `--time-lte`), and a new call can take a while to appear. Then open that execution's trace with `celigo apis execution-logs <id> <executionId>`; step-level trace data is recorded only under `detailed` logging or a debug window. A response step is listed under its `id`, and its stage data can be read only when that id is the builder's own 11-character one: a response `id` you chose (`success`, `notFound`) is refused with 400 `invalid_exp_or_imp_id`, so read the step before it. The older request-log store (`celigo apis logs`) may hold nothing for current calls, and test runs appear in neither, so an empty result from one store doesn't prove the API wasn't called.

Change an API's logging only by patching `logging.mode` or `logging.debugUntil` (`celigo apis set <id> logging.mode=detailed`); a create or a full update ignores `logging` without an error. `noLogging` records no request history, and `standard`, `detailed` and a debug window need payload storage on the account (422 `payload_storage_required`). The modes are listed under `logging` in [base.yml](references/schemas/base.yml).

A step's own requests and responses (`celigo apis debug-requests <id> <exportOrImportId>`) are captured only while that export or import has `debugUntil` set: run `celigo exports enable-debug <exportId> --duration <minutes>` (at most 60; `imports enable-debug` for an import) before the calls you want to see.

## Publishing to API Management

API Management (APIM) is a separate Celigo product that publishes an API, export or import as a managed API with its own console. A published API's read-only `apim` array records the publication (`apiId`, `status` `oaspending` or `published`; [apim.yml](references/schemas/apim.yml)). No CLI command group or Celigo MCP tool publishes: do it in the UI, or over the REST API's `apim` routes. `POST /v1/apim/<exports|imports|apis>/<id>/manageAPI` publishes a resource as a new APIM API (a `PUT` with `apiId` publishes it to an existing one), `POST /v1/apim/<apiId>/<exports|imports|apis>/<id>/openAPIspec` pushes its OpenAPI spec, and `POST /v1/apim/setup` provisions APIM for the account (`PUT /v1/apim/validate` checks a subdomain first), in its production environment only. The routes need the `apim:operations` permission, most of them an APIM license too; a workspace user's APIM access is the `allowAccessToAPIM` flag ([managing-users](../managing-users/SKILL.md)). The CLI can only read: `celigo platform get v1/apim/settings` returns the account's APIM subdomain and service account (`{}` on an account without APIM), and `celigo platform get v1/apim/apis` answers 403 `APIM license is not enabled.` without the license.

## CLI Commands

```bash
# CRUD
celigo apis list
celigo apis get <id>
celigo apis create < api.json
celigo apis update <id> < api.json
celigo apis set <id> key=value [key2=value2 ...]
celigo apis dependencies <id>                 # check before deleting
celigo apis audit <id>                        # change history
celigo apis delete <id>

# Clone (builder-mode only): check the route first, and name the target integration
celigo apis clone <id> --api-version <version> --dry-run
celigo apis clone <id> --api-version <version> --integration <integrationId> [--name <name>] [--description <desc>] [--environment <envId>]

# Pipeline management
celigo apis add-processor <id> <exportOrImportId> [--router <routerId>] [--branch <branchName>]
celigo apis remove-processor <id> <exportOrImportId> [--router <routerId>] [--branch <branchName>]
celigo apis connections <id>
celigo apis replace-connection <id> <connectionId> <newConnectionId>   # every step at once; returns {replacedNodeCount}

# API groups
celigo apis set-group <apiGroupingId> <apiIds...>
celigo apis un...

© celigo · MIT · celigo/ai

Похожие скиллы

Всё по теме «Бэкенд и API» →
notion-api intellectronica Скилл для взаимодействия с Notion API через REST-запросы. Даёт агенту полный доступ к страницам, базам данных, блокам и комментариям — читать, создавать, обновлять и удалять контент. CX Codex +1 94 900установок Webhook Automation Claude Office Skills Скилл для сборки вебхук-интеграций: приём событий, проверка подписи, маршрутизация и преобразование payload. Пригодится, когда нужно связать платежи, GitHub или Slack с внутренними сервисами. CX Codex +1 4 600установок principle-migrate-callers-then-delete-legacy-apis backnotprop Скилл требует сразу переводить вызовы на новый внутренний API и удалять старый код без переходных слоёв совместимости. CX Codex +1 5 200установок plan-zoom-product официальный anthropics Скилл помогает выбрать нужный инструмент Zoom для вашей задачи: REST API, Webhooks, Meeting SDK, Video SDK или другое. Даёт рекомендацию с объяснением трейдоффов. CX Codex +1 2 100установок custom-pages-and-apis eventcatalog Собирает свои страницы и API-роуты внутри проекта EventCatalog: Astro-страницы в pages/, TypeScript-эндпоинты в pages/api/. CX Codex +1 410установок recoup-platform-api-access recoupable Связывает ассистента с API платформы Recoup и внешними коннекторами. Помогает запрашивать данные артистов, редактировать документы и запускать действия без ручной авторизации. CX Codex +1 4 900установок

Из того же набора17

building-tools Скилл для сборки переиспользуемых ресурсов Celigo: логика поиска, импорта и ветвления за одним контрактом входа и выхода. CX Codex +1 2 900установок building-b2b Помогает агенту собирать B2B/EDI-интеграции в Celigo B2B Manager: онбординг партнёров, профили, файловые определения, мониторинг обмена. CX Codex +1 2 900установок configuring-filters Скилл для настройки фильтров Celigo на экспортах, импортах и ветках flow router. Помогает решить, какие записи идут дальше по пайплайну. CX Codex +1 2 900установок configuring-guardrails Скилл для настройки guardrails в Celigo: проверки PII, модерация контента и оценка записей через ИИ. Пригодится, когда интеграция пропускает чувствительные данные. CX Codex +1 2 900установок building-flows Помогает агенту собирать флоу Celigo: расписания, слушатели событий, ветвление записей и обработку ошибок. Пригодится, когда интеграцию нужно не починить, а спроектировать. CX Codex +1 3 000установок writing-sql Пишет SQL-запросы для экспортов и импортов Celigo RDBMS и разбирает ошибки в rdbms.query. Пригодится, когда интеграция читает или пишет в Snowflake, Postgres, MySQL, SQL Server, Oracle, BigQuery или Redshift. CX Codex +1 2 900установок writing-mappings Помогает писать маппинги полей и трансформации в интеграциях Celigo: Mapper 2.0, Transformation 2.0, лукапы и response mapping. CX Codex +1 3 000установок configuring-imports Скилл для настройки импортов Celigo — шага, который записывает записи во внешние системы. Пригодится, когда собираешь интеграцию и нужно выбрать адаптер, настроить лукапы или upsert. CX Codex +1 2 900установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой