Custom Integrations

When the catalog doesn't already have what you need, a custom integration lets you wrap any external API and expose it to your AI Employees as Tools. A custom integration holds the authentication and connection details for one external system; the Tools inside it are the individual capabilities an AI Employee can invoke — and each Tool runs as either an HTTP request or a TypeScript script in a sandbox.

This page walks the end-to-end path: create the integration, configure authentication, add a connection, build and test Tools, publish, and wire them into a workflow. The mechanics of the editor itself are covered in depth in The Tool Editor; this page is the orientation around it.

Who can build them. Creating and editing a custom integration and its Tools requires an admin on the integration's owner tenant. A child tenant granted access can use the integration's Tools but cannot change them.

When to use a custom integration

Reach for a custom integration when you want an AI Employee to act in a system Ema doesn't ship a prebuilt integration for — create a record, look something up, trigger a job. For reading documents into a Knowledge base, use a data connector instead; connectors sync content, custom integrations call APIs.

Step 1 — Create the integration

From the All tab of the Integrations page, create a new integration. Give it a name, a description, and a category. It starts as a draft and appears under Made by you in the catalog. The integration is the container; everything below hangs off it.

Step 2 — Configure authentication

Choose how the integration authenticates the external system. A custom integration declares a structured set of auth fields under one auth scheme:

SchemeUse it for
nonePublic APIs that need no credentials.
api_keyA single API key or token, sent in a header or query parameter.
basicHTTP Basic auth (username and password).
oauth2An authorization-code flow with user consent.

The scheme is fixed once set — you can add or remove individual fields later, but not switch schemes. Mark sensitive fields so the UI masks them; all credentials are encrypted at rest and are never returned in API responses (the UI shows only that a value is present). See Authentication and connections for how schemes, connection templates, and live connections relate.

Step 3 — Add a connection

Create a connection template and connect, so you have a live, authenticated connection to test Tools against. For OAuth2, connecting opens the provider's consent screen; the callback marks the connection active. A connection template can be tenant-level (one shared connection) or user-level (each user connects their own account).

Step 4 — Build Tools

Open the integration's Tools section and add a Tool. Every Tool — whichever way it executes — has a name, an auto-generated internal name, a description (which the agent reads to decide when to call it), a typed input schema, and an output schema. Pick a Tool type:

HTTP Tool

An HTTP Tool makes one declarative outbound request. You set the method (GET, POST, PUT, PATCH, DELETE), the URL, headers, query parameters, and a body, using {{...}} template references that resolve at call time:

  • {{input.X}} — a value from the Tool's input schema, supplied by the caller.
  • {{credential.X}} — a credential from the active connection.
  • {{setting.X}} — a template-level integration setting, such as a base URL.

At call time Ema's http executor resolves the templates, injects the connection's auth, runs the request, and returns the response — you never handle the token yourself. Use an HTTP Tool whenever a single request does the job.

TypeScript script Tool

A TS Script Tool runs a TypeScript function in a sandbox via the ts_script executor. Reach for it when one request isn't enough — you need to transform inputs, branch on a response, page through results, or call several endpoints in sequence. The editor types your code against an Inputs interface generated from your input schema, and you make authenticated calls back to the integration's endpoints through a provided binding; the script never sees raw credentials. Script Tools cannot call an LLM — reasoning belongs in the agent that calls the Tool, not in the Tool.

You can switch a draft between HTTP and TS Script; the editor warns before discarding type-specific content. For the full field reference, the linter rules, the test panel, and validation, see The Tool Editor.

Step 5 — Test, publish, and wire in

Each Tool starts as a draft and is callable only after you publish it:

  1. In the editor's Test panel, pick a connection, fill in a JSON input matching your schema, and Run test against the real system.
  2. Validate checks the saved configuration for broken references — for example a {{credential.X}} that no longer exists.
  3. Publish moves the Tool from draft to published. Edits to a published Tool go live immediately, so make corrections deliberately.
  4. Add the integration's published Tools to an AI Employee's workflow through the agent's tool list, exactly as you would a catalog integration's Tools.

How a custom Tool runs at call time

You never choose an execution strategy when wiring a Tool into a workflow. The agent calls the integrations service, which routes the call to the executor recorded on the Tool — http for HTTP Tools, ts_script for TypeScript Tools. Either way, the outbound payload passes through Ema's PII rendering layer before it leaves the platform, and every execution is recorded in the audit trail. See How Tool calls are executed for the full routing and PII behavior.

What's next

  • The Tool Editor — the complete editor reference: input/output schemas, references, HTTP and TS Script details, test, validate, and publish.
  • Integrations Hub — the catalog, authentication schemes, connections, and executor routing.
  • Data Connectors — sync external documents into Knowledge bases instead of calling an API.

Last updated: Jul 3, 2026