CumulusDocs
Open Studio
On this page

Bindings and integrations

Bindings connect an agent to your environment. The graph refers to a name such as customer_api; development can map it to your test backend, while production maps it to the production backend. Your graph and tool contracts stay the same.

An integration selects how that agent uses phone numbers, initial context and lifecycle notifications. Publishing includes its context and notification configuration. Assigning numbers is a separate step so a graph change does not silently change live routing.

Bind an endpoint, a number and events

This example uses the agent from the tutorial project. The workspace already contains the imported number and tool/event secrets. Obtain their IDs and current versions from that workspace:

typescript
import { defineEnvironment, defineIntegration } from '@cumulus/sdk/agent';
import { agent } from './project.js';

function required(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`Set ${name}`);
  return value;
}

export const bindings = defineEnvironment({
  endpoints: {
    customer_api: {
      baseUrl: required('CUSTOMER_API_URL'),
      auth: {
        scheme: 'bearer',
        secret_ref: {
          id: required('TOOL_SECRET_ID'),
          version: required('TOOL_SECRET_VERSION'),
        },
      },
    },
  },
  numbers: { test_number: required('TEST_NUMBER_ID') },
  notifications: {
    customer_events: {
      url: required('CUSTOMER_EVENTS_URL'),
      secretRef: {
        id: required('EVENT_SECRET_ID'),
        version: required('EVENT_SECRET_VERSION'),
      },
    },
  },
});

export const integration = defineIntegration({
  key: 'service_guide',
  agent,
  inbound: { numberBinding: 'test_number' },
  outbound: { callerIdBinding: 'test_number' },
  events: {
    destinationBinding: 'customer_events',
    subscriptions: ['run.ended', 'recording.updated', 'analysis.updated'],
  },
});

The tool's execution.binding: 'customer_api' now resolves to your endpoint and authentication reference. test_number resolves to an imported number resource ID. A call's to field is different: it holds the recipient's E.164 phone number.

Secret references contain an opaque ID and version, never secret bytes. Your server needs the matching bytes from your secret manager. When you have a SecretMetadata response, secretReference(metadata) builds the reference from its id and current_version.

Compile, publish and assign routes

Pass the integration when compiling or previewing so its configuration is included:

typescript
import { compileAgent, authoring } from '@cumulus/sdk/agent';

const definition = compileAgent(agent, bindings, integration); // local validation
const plan = await authoring.preview(client, agent, bindings, { integration });

Here client is your authenticated Cumulus client. The release workflow covers reviewing the plan, applying it and saving the publication receipt. Once that publication is the selected head, assign the integration's numbers:

typescript
import { assignIntegration } from '@cumulus/sdk/runtime';

const assigned = await assignIntegration(client, integration, bindings, receipt);

The CLI exposes these stages as preview, apply, publish and the explicit route command. Before routing, send an authenticated request to the deployed tool endpoint and check its result. Save the previous number assignments.

Assignment checks that the current head matches the receipt publication, then updates imported numbers. It does not purchase a number or place a call. Multiple updates are separate operations: inspect every returned assignment and avoid changing the head concurrently.

Add inbound context

If the agent includes a context resolver action, extend inbound with its action key and declared output names:

typescript
import { initialContext } from './tools.js';

const inbound = {
  numberBinding: 'test_number',
  contextResolver: initialContext.key,
  contextOutputs: ['demo_channel'],
};

Pass this inbound value to defineIntegration. The tutorial exports initialContext from src/tools.ts; the action must exist in the agent definition and its server must return those string variables. See the context adapter. A phone lookup can select a candidate account; use your business verification flow before exposing or changing account data.

Binding reference

BindingValue
endpoints[alias]HTTPS baseUrl, native auth with a pinned secret reference, optional noncredential headers.
numbers[alias]An already imported number resource ID.
notifications[alias]Public HTTPS callback url and pinned secretRef.
editsAdditional typed agent configuration checked before publication.
Integration propertyPurpose
inbound.numberBindingNumber alias for incoming calls.
inbound.contextResolver, contextOutputsInitial-context action and allowed variables.
outbound.callerIdBindingNumber alias for outbound assignment.
events.destinationBinding, subscriptionsEvent callback and selected lifecycle events.

Tool endpoints use HTTPS on port 443. Tool paths are absolute: /cumulus/tools/guide resolves from the origin even when baseUrl contains a pathname. Include the full public prefix in the path, without a query, fragment or origin change. Use native authentication references instead of literal credential headers.

Configure the underlying models, secrets and carrier resources in the selected workspace. Where required, use a native telephony edit for trunk and outbound from settings; callerIdBinding alone is not that configuration. The CLI selects one integration per agent; use the library when you need to choose among integrations explicitly.

Content version f70c9aacCustomer SDKMarkdown source
Bindings and integrations · Cumulus developer docs