building-apis

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, or exposing lookup/write operations as a REST interface that returns a structured response.

By celigo · 1,046 installs

npx skills add celigo/ai --skill building-apis

Source repository · Upstream listing

<! 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: 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. 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 route