API Reference
Reference material for @monad-inc/embed/connect: the createConnectorFrame options,
theming tokens, the request thunk, catalog reads, connector icons, the security model,
and the backend route contract.
What the package gives you
Everything ships in @monad-inc/embed, a public npm package with TypeScript types and no
runtime dependencies. Import from the /connect subpath.
The iframe mount:
createConnectorFrame(options)— returns aConnectorFramehandle with.destroy().
Pipeline lifecycle helpers (each takes a request thunk):
buildDevNullPipeline({ request, org, inputId, inputName })findIntegrationPipeline({ request, org, inputId })setIntegrationEnabled({ request, org, pipelineId, enabled })— plusenableIntegration/disableIntegrationdeleteIntegration({ request, org, pipelineId?, inputId?, outputId?, cleanup })
Constants and types: CLEANUP_FULL, CLEANUP_KEEP_OUTPUT, CLEANUP_PIPELINE_ONLY,
and the types Appearance, ComponentKind, ConnectorFrame, ConnectorFrameOptions,
BuiltPipeline, CleanupPolicy, ResolvedIntegration, MonadRequest, and the protocol
messages.
See Connector Lifecycle for how the helpers and constants fit together.
createConnectorFrame options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
container | HTMLElement | string | Yes | — | Element (or CSS selector) the iframe is appended to. |
sessionToken | string | Yes | — | Short-lived token from POST /v3/sessions (your backend mints this). |
organizationId | string | Yes | — | Monad team org id the session is scoped to. Same value you passed to /v3/sessions. |
kind | 'input' | 'output' | Yes | — | Which catalog the connector belongs to. |
typeId | string | Yes | — | Connector type slug, e.g. 'aws-cloudtrail', 'okta-systemlog'. |
existingId | string | No | — | Pass to edit an existing connector. Omit to create a new one. |
displayName | string | No | the connector type's name | Title shown in the iframe header. |
name | string | No | type name + unique suffix | Name for the created connector. On edit, omit to keep the existing name. |
description | string | No | the connector type's description | Description for the created connector. On edit, omit to keep the existing description. |
isNameEditable | boolean | No | false | Show an editable name input in the iframe (prefilled with name if provided, else the type name). A non-empty name is required when shown. |
isDescriptionEditable | boolean | No | false | Show an editable description input in the iframe (prefilled with description if provided). |
appearance | Appearance | No | Monad defaults | Theming tokens (see below). |
synthetic | boolean | No | false | Exposes Monad's internal synthetic-data toggle. Keep off in production. |
frameOrigin | string | No | https://app.monad.com/embed | Override only for non-prod testing. |
apiBase | string | No | https://app.monad.com/api | Override only for non-prod testing. |
onSave | (c: { id, name? }) => void | No | — | Fired when the user saves successfully. |
onCancel | () => void | No | — | Fired when the user cancels. |
onError | (message: string) => void | No | — | Fired on a save / test / load failure. |
The call returns a handle:
Code
Theming with appearance
Six tokens, applied as CSS custom properties inside the iframe:
Code
The iframe is cross-origin, so your stylesheets can't bleed in — by design. These six
tokens are the main theming channel. appearance applies once at mount, so changing a
token means a destroy() and remount (see
Best Practices). For cases
the tokens can't cover, stylesheets replaces Monad's CSS wholesale.
The MonadRequest thunk
MonadRequest is the seam between the lifecycle helpers and your authentication. You
build a function with your API key already closed over and hand it to the helpers; they
call it when they need the Monad API, and never see the key. Build it once, on your
backend:
Code
Retries, logging, or a proxy all live inside this function, out of the SDK's way.
Rendering your own catalog
The type list and a tenant's configured connectors are plain Monad API reads behind your backend:
- Available types (global):
GET /v1/{kind}s, each withtype_idandname. You rarely surface all 300+; keep a server-side allow-list of thetype_ids you support. - A tenant's configured connectors (team-scoped):
GET /v1/{org}/{kind}s, wrapped as{ inputs: [...] }or{ outputs: [...] }. The configured list is paginated; pass?limit=&offset=.
Code
:::warning Field-name mismatch
Configured rows carry the type slug as type, not type_id. Normalize it so the rest of
your app sees one field.
:::
Connector icons
Connector icons are static SVGs at a public, no-auth, CORS-enabled endpoint keyed by the
same typeId you pass to createConnectorFrame:
Code
Render it in an <img> and fall back to your own placeholder on a 404:
Code
Notes:
- Responses are immutable per
typeIdand carry a 7-dayCache-Control, so the browser and any CDN cache them automatically — no need to bust the URL. - The icon is the vendor's, not the connector's. Many
typeIds share one logo (every AWS service resolves to the AWS icon). If you need to tell two connectors of the same vendor apart, use the display name alongside the logo. - Always handle
404— new or custom connectors may not have a dedicated logo yet.
The full endpoint reference, including the JSON mapping-lookup companion endpoint, is in
docs/connector-icons.md
in the @monad-inc/embed repo.
Security model
- Cross-origin iframe. The form runs on
app.monad.com, not on your domain. The browser's same-origin policy means your JavaScript cannot read the iframe's DOM or any value the user types. - Session tokens are short-lived. Default 30 min, scoped to a single team. Compromise of a session token is bounded; compromise of the long-lived API key is not — keep it on your backend.
postMessagewith strict origin checks. Every message between your page and the iframe is validated against the expected origin in both directions.SameSite=Laxcookies. Any cookies you set on your own domain do not travel into the Monad iframe.- No host JavaScript in the iframe. You cannot inject script or CSS; the only
customization channel is the six
appearancetokens (andstylesheets).
Appendix A — backend route contract
The endpoints your backend exposes to your frontend. Paths are your choice; the shapes and the Monad call behind each are what matter.
| Method and path | Body / query | Monad call behind it | Returns |
|---|---|---|---|
GET /api/monad/config | (none) | static | { frameOrigin, apiBase } |
POST /api/session | { tenantId } | POST /v3/sessions | { session_token, expires_at, organizationId } |
GET /api/catalog | ?kind=input|output | GET /v1/{kind}s | CatalogType[] |
GET /api/connectors | ?kind=&tenantId= | GET /v1/{org}/{kind}s | ConfiguredConnector[] |
POST /api/build-pipeline | { tenantId, inputId, inputName } | buildDevNullPipeline or POST /v2/{org}/pipelines/ | BuiltPipeline |
POST /api/integration-action | { tenantId, action, inputId } | findIntegrationPipeline, then setIntegrationEnabled or deleteIntegration | status or result |
Add POST /api/team ({ name } → POST /v3/{yourOrgId}/organizations, returns
{ id }) if you provision teams programmatically.
Appendix B — what you import vs. what you build
| Concern | Ships in @monad-inc/embed | You write |
|---|---|---|
| Mount the iframe | createConnectorFrame | the container and chrome |
| Authenticated requests | MonadRequest type | the thunk (monadRequest) |
| Session mint | (none) | POST /v3/sessions endpoint |
| Catalog reads | (none) | GET /v1/... wrappers |
| Zero-setup pipeline | buildDevNullPipeline | (none) |
| Real input-to-output pipeline | (none) | POST /v2/{org}/pipelines/ |
| Status, pause, resume | findIntegrationPipeline, setIntegrationEnabled | thin route wrappers |
| Delete and cleanup | deleteIntegration, CLEANUP_* | resolve-then-act route |
| Tenant-to-team mapping | (none) | your server-side record |
Related
@monad-inc/embedon npmmonad-inc/embedon GitHub — the SDK source,USAGE.md, and the connector-icons guide.
Support
For additional support contact support@monad.com