Custom Integrations
Custom integrations are only available for enterprise clients at this time. Please reach out to sales@edisonscientific.com for commercial inquiries.
Overview
An integration gives an agent authenticated access to an external API — the mechanism behind the built-in Notion, Slack, Teams, Google Drive, and GitHub connections. This page covers registering your own API as a first-class integration, using that same interface.
The agent never accesses your credential. Keys are stored in a secret manager, and the sandbox's egress proxy injects them into outbound requests in transit. The key is not in the agent's environment at all — so it cannot be exfiltrated by a prompt injection or leaked in a transcript.
How it works
your agent ──HTTP──► network sidecar ──► your API
│
└── looks up the provider by domain,
injects the credential from Secret ManagerA provider entry in the integrations catalog declares the API: its domains, how the credential is presented, and a URL to validate a key against.
That entry drives the sandbox proxy's TLS-intercept domain list and its credential-injection rules.
A connection attaches an actual credential at user or organization scope.
At request time, resolution prefers the calling user's own credential and falls back to the organization's.
1. Register the provider
from edison_client import EdisonClient
client = EdisonClient()
glyph = client.create_custom_integration(
CustomIntegrationSpec(
name="Glyph Structure Recognition",
domains=["glyph.ml.internal.example.com"],
auth_method=IntegrationAuthMethod.BEARER,
auth_flow=IntegrationAuthFlow.STATIC_KEY,
header_name="Authorization",
validation_url="https://glyph.ml.internal.example.com/v1/models",
instructions=(
"Paste a Glyph API token from the ML platform console. "
"Read scope on /v1/ocsr and /v1/markush is sufficient."
),
image="https://cdn.example.com/glyph-logo.png",
),
organization_id=42, # omit to publish tenant-wide
)
glyph.id # UUID used by every call belowRegistering creates the catalog entry only — no credential is stored yet.
CustomIntegrationSpec
name
str
yes
Display name. Unique across the catalog.
domains
list[str]
yes
Hosts the proxy intercepts and injects credentials for. Bare hostnames — no scheme, no path.
auth_method
IntegrationAuthMethod
yes
How the credential is presented (below)
auth_flow
IntegrationAuthFlow
no (static_key)
How the credential is obtained
header_name
str
no (Authorization)
Header the credential is injected into; for query_param, the parameter name
instructions
str
yes
Shown in the connect dialog: where a user gets a key
image
str
yes
Logo URL for the UI tile
validation_url
str | None
no
Cheap authenticated GET used to prove a stored key works
oauth_authorization_url
str | None
OAuth only
Authorization endpoint
oauth_token_url
str | None
OAuth only
Token endpoint
oauth_scopes
list[str] | None
OAuth only
Requested scopes
IntegrationAuthMethod — how the credential rides on the request:
bearer
Authorization: Bearer <key>
header
<header_name>: <key>
query_param
?<param_name>=<key>
query_paramis declarable but not yet injectable. The credential lookup path raisesNotImplementedErrorfor it. Usebearerorheaderuntil that lands.
IntegrationAuthFlow:
static_key
A long-lived key pasted by a user or admin
oauth2
Authorize → callback → refresh loop
2. Attach a credential
Organization scope — admin only, and by default all member's agents inherit it:
User scope — personal, and takes priority over the org credential for that user's agents:
provider_catalog_id
UUID
Provider to connect
api_key
str
Your key for that API
organization_id
int | None
None → user scope; set → org scope (admin)
expires_at
datetime | None
Optional expiry, surfaced in the UI before it bites
The key goes straight to the secret manager; only a secret reference is written to the backend.
3. Validate before anyone depends on it
Re-probes the stored credential against validation_url. Runs automatically on connect, and on demand thereafter — the cheapest way to distinguish "the integration is broken" from "the agent did something wrong".
4. Use it
Nothing further is required of the agent or of you. The agent calls the API normally, with no credential anywhere in its code:
In practice you would pair the integration with a skill — a markdown guide telling the agent which endpoints exist, how to choose between them, and how to report results.
To guarantee an agent always has that guidance rather than discovering it, name the skill in a profile's auto_skills and deploy that profile as your own job:
The integration handles access; the skill handles judgment; the profile guarantees the skill is loaded. See configuration.md.
5. Rotate and offboard
Rotation can be achieved by overwriting, and offboarding via a revoke method.
revoke_integration disconnects the provider and deletes the stored credential.
Listing what is available
IntegrationProvider
id
UUID
Catalog ID used by connect / validate / revoke
name
str
Display name
domains
list[str]
Intercepted hosts
auth_flow
IntegrationAuthFlow
static_key or oauth2
connected
bool
Whether a usable credential is attached for the caller
org_managed
bool
Credential comes from the organization, not the user
last_validated
datetime | None
Last successful validation
last_used
datetime | None
Last agent request that used it
expires_at
datetime | None
Credential expiry, if declared
IntegrationConnection
provider
str
provider_catalog_id
UUID
scope
IntegrationScope — user or organization
connected
bool
IntegrationValidation
provider
str
valid
bool
error
str | None
Constraints worth knowing up front
Provider
nameis globally unique in the catalog.A new domain becomes interceptable only after the sandbox proxy configuration regenerates. This happens on an infrastructure level within minutes but is not instant.
query_paramcredentials are not injectable yet (see above).User credentials override org credentials.
Providers can be mutually exclusive. The catalog supports a mutex group, so at most one provider in a group may be connected per user — relevant if you register several entries for the same underlying service.
Last updated
