Skip to content

Latest commit

 

History

History
1212 lines (808 loc) · 46 KB

File metadata and controls

1212 lines (808 loc) · 46 KB

Interchange Hub API

Endpoint Index

Method Path Summary
GET /api/me Get current user profile
GET /api/me/principals List principals across all tenants
GET /api/me/agents List agents across all tenants
GET /api/me/instances List running agent instances across all tenants
GET /api/me/sessions List sessions across all tenants
GET /api/me/approvals List pending approvals across all tenants
POST /api/tenants Create a tenant
GET /api/tenants/:tenantId Get tenant details
PATCH /api/tenants/:tenantId Update tenant config
GET /api/models List available models
GET /api/tenants/:tenantId/principals List principals in the tenant
GET /api/tenants/:tenantId/principals/:principalId Get principal details
PATCH /api/tenants/:tenantId/principals/:principalId Update principal status
DELETE /api/tenants/:tenantId/principals/:principalId Remove principal from tenant
POST /api/tenants/:tenantId/members/invite Invite a user to the tenant
GET /api/tenants/:tenantId/roles List roles in the tenant
POST /api/tenants/:tenantId/roles Create a custom role
GET /api/tenants/:tenantId/roles/:roleId Get role details
PATCH /api/tenants/:tenantId/roles/:roleId Update a role
DELETE /api/tenants/:tenantId/roles/:roleId Delete a custom role
POST /api/tenants/:tenantId/principals/:principalId/roles/:roleId Assign a role to a principal
DELETE /api/tenants/:tenantId/principals/:principalId/roles/:roleId Remove a role from a principal
GET /api/tenants/:tenantId/grants List grants in the tenant
POST /api/tenants/:tenantId/grants Create a grant
GET /api/tenants/:tenantId/grants/:grantId Get grant details
PATCH /api/tenants/:tenantId/grants/:grantId Update a grant
DELETE /api/tenants/:tenantId/grants/:grantId Revoke a grant
POST /api/tenants/:tenantId/principals/:principalId/evaluate Evaluate grants for a principal
GET /api/tenants/:tenantId/agents/definitions List agents in the tenant
POST /api/tenants/:tenantId/agents/definitions Create an agent
GET /api/tenants/:tenantId/agents/definitions/:agentId Get agent details
PATCH /api/tenants/:tenantId/agents/definitions/:agentId Update agent definition
DELETE /api/tenants/:tenantId/agents/definitions/:agentId Retire an agent
GET /api/tenants/:tenantId/agents/definitions/:agentId/versions List agent versions
POST /api/tenants/:tenantId/agents/definitions/:agentId/rollback Rollback to a previous version
POST /api/tenants/:tenantId/agents/instances Deploy an agent instance
GET /api/tenants/:tenantId/agents/instances List agent instances
GET /api/tenants/:tenantId/agents/instances/blobs/:blobId Fetch a blob by ID
GET /api/tenants/:tenantId/agents/instances/:instanceId Get instance detail
DELETE /api/tenants/:tenantId/agents/instances/:instanceId Stop an instance
GET /api/tenants/:tenantId/agents/instances/:instanceId/health Get instance health
GET /api/tenants/:tenantId/agents/instances/:instanceId/offerings List instance offerings
GET /api/tenants/:tenantId/agents/instances/:instanceId/events SSE event stream
POST /api/tenants/:tenantId/agents/instances/:instanceId/abort Abort current operation
POST /api/tenants/:tenantId/agents/instances/:instanceId/mail Send mail to the agent
GET /api/tenants/:tenantId/agents/instances/:instanceId/mail List mail for an instance
GET /api/tenants/:tenantId/agents/instances/:instanceId/turns List inference turns for an instance
GET /api/tenants/:tenantId/approvals List pending approvals in the tenant
GET /api/tenants/:tenantId/approvals/:approvalId Get approval details
POST /api/tenants/:tenantId/approvals/:approvalId/approve Approve an action
POST /api/tenants/:tenantId/approvals/:approvalId/reject Reject an action
GET /api/tenants/:tenantId/wallets List wallets in the tenant
POST /api/tenants/:tenantId/wallets Create a wallet
GET /api/tenants/:tenantId/wallets/:walletId Get wallet details
PATCH /api/tenants/:tenantId/wallets/:walletId Update wallet config
DELETE /api/tenants/:tenantId/wallets/:walletId Deactivate a wallet
GET /api/tenants/:tenantId/wallets/:walletId/transactions List transactions
GET /api/tenants/:tenantId/providers List providers
POST /api/tenants/:tenantId/providers Create a provider definition
GET /api/tenants/:tenantId/providers/:providerId Get provider details
PATCH /api/tenants/:tenantId/providers/:providerId Update a provider definition
DELETE /api/tenants/:tenantId/providers/:providerId Remove a provider definition
GET /api/tenants/:tenantId/oauth-clients List OAuth client registrations
POST /api/tenants/:tenantId/oauth-clients Register an OAuth client
GET /api/tenants/:tenantId/oauth-clients/:oauthClientId Get OAuth client details
PATCH /api/tenants/:tenantId/oauth-clients/:oauthClientId Update an OAuth client registration
DELETE /api/tenants/:tenantId/oauth-clients/:oauthClientId Remove an OAuth client registration
GET /api/tenants/:tenantId/credentials List credentials
POST /api/tenants/:tenantId/credentials Store a credential
GET /api/tenants/:tenantId/credentials/resolve/:name Resolve a credential by name
GET /api/tenants/:tenantId/credentials/:credentialId Get credential metadata
PATCH /api/tenants/:tenantId/credentials/:credentialId Rotate or update a credential
DELETE /api/tenants/:tenantId/credentials/:credentialId Revoke a credential
GET /api/tenants/:tenantId/offerings Search offerings
POST /api/tenants/:tenantId/offerings Register an offering
GET /api/tenants/:tenantId/offerings/:offeringId Get offering details
PATCH /api/tenants/:tenantId/offerings/:offeringId Update an offering
DELETE /api/tenants/:tenantId/offerings/:offeringId Remove an offering
GET /api/tenants/:tenantId/agents/:agentId/logs Get agent logs
GET /api/tenants/:tenantId/agents/:agentId/metrics Get agent metrics
GET /api/tenants/:tenantId/traces Query distributed traces
GET /api/tenants/:tenantId/traces/:traceId Get a full trace
GET /api/tenants/:tenantId/federation List federation trust relationships
POST /api/tenants/:tenantId/federation Establish federation trust
DELETE /api/tenants/:tenantId/federation/:targetTenantId Revoke federation trust
GET /api/tenants/:tenantId/agents/:agentId/data List files in agent working directory
GET /api/tenants/:tenantId/agents/:agentId/data/* Read a file from agent storage
GET /api/tenants/:tenantId/agents/:agentId/history List commits and checkpoints
GET /api/tenants/:tenantId/agents/:agentId/history/:ref Show changes in a commit
GET /api/tenants/:tenantId/agents/:agentId/branches List branches
POST /api/tenants/:tenantId/agents/:agentId/history/:ref/restore Restore agent data to a previous state
POST /api/sidecars Register or update a sidecar
GET /api/sidecars List all sidecars
GET /api/sidecars/:id Get a sidecar by ID
DELETE /api/sidecars/:id Deregister a sidecar
POST /api/sidecars/:id/heartbeat Record a sidecar heartbeat

User

GET /api/me

Get current user profile

200: UserProfile -- User profile 401: ErrorResponse -- Not authenticated

GET /api/me/principals

List principals across all tenants

Returns all of the authenticated user's principals across tenants, with tenant name, roles, and status in each.

Query: cursor?, limit?

200: unknown -- List of principals across tenants 401: ErrorResponse -- Not authenticated

GET /api/me/agents

List agents across all tenants

Aggregates agents from all tenants the user belongs to. Each result is tagged with tenantId.

Query: cursor?, limit?

200: unknown -- Agents across tenants

GET /api/me/instances

List running agent instances across all tenants

Aggregates running agent instances from all tenants the user belongs to. Each result is tagged with tenantId.

Query: cursor?, limit?

200: unknown -- Instances across tenants

GET /api/me/sessions

List sessions across all tenants

Aggregates active sessions from all tenants the user belongs to. Each result is tagged with tenantId.

200: SessionSummary[] -- Sessions across tenants

GET /api/me/approvals

List pending approvals across all tenants

Aggregates pending approval requests from all tenants the user belongs to. Each result is tagged with tenantId.

200: ApprovalSummary[] -- Approvals across tenants

Tenants

POST /api/tenants

Create a tenant

Creates a new tenant. The authenticated user becomes the owner with a principal and default owner role.

Body: CreateTenant

201: TenantResponse -- Tenant created 400: ErrorResponse -- Validation error

GET /api/tenants/:tenantId

Get tenant details

200: TenantResponse -- Tenant details 403: ErrorResponse -- Not a member of this tenant 404: ErrorResponse -- Tenant not found

PATCH /api/tenants/:tenantId

Update tenant config

Requires admin or higher grant within the tenant.

Body: UpdateTenant

200: TenantResponse -- Tenant updated 403: ErrorResponse -- Insufficient grants

GET /api/tenants/:tenantId/federation

List federation trust relationships

Query: cursor?, limit?

200: unknown -- Federation trusts

POST /api/tenants/:tenantId/federation

Establish federation trust

Creates a trust relationship with another tenant for cross-tenant agent discovery and interaction.

Body: CreateFederationTrust

201: FederationTrust -- Trust established 400: ErrorResponse -- Validation error

DELETE /api/tenants/:tenantId/federation/:targetTenantId

Revoke federation trust

204: (no content) -- Trust revoked 404: ErrorResponse -- Trust not found

Discovery

GET /api/models

List available models

Lists available models across configured providers with capabilities, pricing, and limits.

200: ModelInfo[] -- List of models

GET /api/tenants/:tenantId/offerings

Search offerings

Searches offerings across discoverable agents in the tenant and federated tenants. Filterable by offering name, pricing range, and payment method.

Query: name?, minPrice?, maxPrice?, paymentMethod?, cursor?, limit?

200: unknown -- List of offerings

POST /api/tenants/:tenantId/offerings

Register an offering

Registers an offering for an agent. The agent must belong to the tenant.

Body: CreateOffering

201: OfferingDetail -- Offering registered 400: ErrorResponse -- Validation error 404: ErrorResponse -- Agent not found

GET /api/tenants/:tenantId/offerings/:offeringId

Get offering details

Returns pricing, agent info, and request/response type information.

200: OfferingDetail -- Offering details 404: ErrorResponse -- Offering not found

PATCH /api/tenants/:tenantId/offerings/:offeringId

Update an offering

Body: UpdateOffering

200: OfferingDetail -- Offering updated 404: ErrorResponse -- Offering not found

DELETE /api/tenants/:tenantId/offerings/:offeringId

Remove an offering

204: (no content) -- Offering removed 404: ErrorResponse -- Offering not found

Principals

GET /api/tenants/:tenantId/principals

List principals in the tenant

Lists all principals (users and agents) in the tenant. Filterable by kind and status.

Query: kind?: user|agent, status?: active|suspended|invited|deactivated, cursor?, limit?

200: unknown -- List of principals

GET /api/tenants/:tenantId/principals/:principalId

Get principal details

Returns principal details including kind, status, assigned roles, and effective grants.

200: PrincipalResponse -- Principal details 404: ErrorResponse -- Principal not found

PATCH /api/tenants/:tenantId/principals/:principalId

Update principal status

Activate, suspend, or deactivate a principal.

Body: UpdatePrincipal

200: PrincipalResponse -- Principal updated 403: ErrorResponse -- Insufficient grants

DELETE /api/tenants/:tenantId/principals/:principalId

Remove principal from tenant

Removes a user or agent principal from the tenant. For agents, use agent deletion instead.

204: (no content) -- Principal removed 403: ErrorResponse -- Insufficient grants

POST /api/tenants/:tenantId/members/invite

Invite a user to the tenant

Invites a user by email. Creates a principal with invited status and optionally assigns a role.

Body: InviteMember

201: PrincipalResponse -- Invitation sent 400: ErrorResponse -- Validation error

Roles

GET /api/tenants/:tenantId/roles

List roles in the tenant

Lists both system roles (owner, admin, member) and custom roles.

Query: cursor?, limit?

200: unknown -- List of roles

POST /api/tenants/:tenantId/roles

Create a custom role

Body: CreateRole

201: RoleResponse -- Role created 400: ErrorResponse -- Validation error

GET /api/tenants/:tenantId/roles/:roleId

Get role details

Returns role details including attached grants.

200: RoleResponse -- Role details 404: ErrorResponse -- Role not found

PATCH /api/tenants/:tenantId/roles/:roleId

Update a role

Update name or description. System roles cannot be modified.

Body: UpdateRole

200: RoleResponse -- Role updated 403: ErrorResponse -- Cannot modify system role

DELETE /api/tenants/:tenantId/roles/:roleId

Delete a custom role

Deletes a custom role. Fails if principals are currently assigned to it. System roles cannot be deleted.

204: (no content) -- Role deleted 400: ErrorResponse -- Role still assigned to principals 403: ErrorResponse -- Cannot delete system role

POST /api/tenants/:tenantId/principals/:principalId/roles/:roleId

Assign a role to a principal

Assigns a role to a user or agent principal within the tenant.

204: (no content) -- Role assigned 404: ErrorResponse -- Principal or role not found

DELETE /api/tenants/:tenantId/principals/:principalId/roles/:roleId

Remove a role from a principal

204: (no content) -- Role removed 404: ErrorResponse -- Assignment not found

Grants

GET /api/tenants/:tenantId/grants

List grants in the tenant

Lists all grants. Filterable by principalId, roleId, resource pattern, and effect.

Query: principalId?, roleId?, resource?, effect?: allow|deny|ask, cursor?, limit?

200: unknown -- List of grants

POST /api/tenants/:tenantId/grants

Create a grant

Creates a grant targeting either a role or a principal directly. Exactly one of roleId or principalId must be provided.

Body: CreateGrant

201: GrantResponse -- Grant created 400: ErrorResponse -- Validation error

GET /api/tenants/:tenantId/grants/:grantId

Get grant details

200: GrantResponse -- Grant details 404: ErrorResponse -- Grant not found

PATCH /api/tenants/:tenantId/grants/:grantId

Update a grant

Update effect, conditions, or expiry on an existing grant.

Body: UpdateGrant

200: GrantResponse -- Grant updated 404: ErrorResponse -- Grant not found

DELETE /api/tenants/:tenantId/grants/:grantId

Revoke a grant

204: (no content) -- Grant revoked 404: ErrorResponse -- Grant not found

POST /api/tenants/:tenantId/principals/:principalId/evaluate

Evaluate grants for a principal

Evaluates what would happen if a principal attempted an operation. Returns the resolved effect and all matching grants. Useful for debugging authorization.

Body: EvaluateRequest

200: EvaluateResult -- Evaluation result 404: ErrorResponse -- Principal not found

Agents

GET /api/tenants/:tenantId/agents/definitions

List agents in the tenant

Filterable by offering and status.

Query: offering?, status?: deployed|stopped, cursor?, limit?

200: unknown -- List of agents

POST /api/tenants/:tenantId/agents/definitions

Create an agent

Creates an agent definition. Grant requirements are stored as a manifest and resolved at instance launch time.

Body: CreateAgent

201: AgentResponse -- Agent created 400: ErrorResponse -- Validation error

GET /api/tenants/:tenantId/agents/definitions/:agentId

Get agent details

Returns the agent definition, status, health, and capabilities.

200: AgentResponse -- Agent details 404: ErrorResponse -- Agent not found

PATCH /api/tenants/:tenantId/agents/definitions/:agentId

Update agent definition

Updates the agent definition and creates a new version. The new version is deployed alongside the current version until health checks pass.

Body: UpdateAgent

200: AgentResponse -- Agent updated 400: ErrorResponse -- Validation error

DELETE /api/tenants/:tenantId/agents/definitions/:agentId

Retire an agent

Retires the agent definition and marks all running instances as stopped. Does not signal running sidecars; in-flight sessions continue until the sidecar disconnects.

204: (no content) -- Agent retirement initiated 404: ErrorResponse -- Agent not found

GET /api/tenants/:tenantId/agents/definitions/:agentId/versions

List agent versions

Lists all versions with their deployment status.

Query: cursor?, limit?

200: unknown -- List of versions

POST /api/tenants/:tenantId/agents/definitions/:agentId/rollback

Rollback to a previous version

Shifts traffic back to the specified version. The current version is stopped.

Body: RollbackRequest

200: AgentResponse -- Rollback initiated 400: ErrorResponse -- Invalid version

Instances

POST /api/tenants/:tenantId/agents/instances

Deploy an agent instance

Creates a new running instance of the specified agent definition. Resolves the definition's credential and grant requirements, materializes grants on a new agent principal, provisions the agent on a sidecar, and starts it. The invoker can provide invokerGrants to delegate additional capabilities, resolved against the invoker's own authority at launch.

Body: CreateAgentInstance

201: AgentInstanceResponse -- Instance deployed 404: ErrorResponse -- Agent definition not found 409: ErrorResponse -- Agent not launchable 502: ErrorResponse -- Sidecar unavailable

GET /api/tenants/:tenantId/agents/instances

List agent instances

Lists agent instances in the tenant. Filterable by agentId and status.

Query: agentId?, status?: deployed|running|updating|error|stopped, cursor?, limit?

200: unknown -- List of instances

GET /api/tenants/:tenantId/agents/instances/blobs/:blobId

Fetch a blob by ID

Returns raw bytes for a MIME part. Blob IDs are issued by the mail parsing layer.

200: (no content) -- Blob bytes 400: ErrorResponse -- Invalid blob ID 403: ErrorResponse -- Forbidden 404: ErrorResponse -- Blob not found

GET /api/tenants/:tenantId/agents/instances/:instanceId

Get instance detail

Returns instance runtime state including status, public key, and sidecar assignment.

200: AgentInstanceResponse -- Instance detail 404: ErrorResponse -- Instance not found

DELETE /api/tenants/:tenantId/agents/instances/:instanceId

Stop an instance

Stops the running instance and undeploys the agent from the sidecar.

204: (no content) -- Instance stopped 404: ErrorResponse -- Instance not found 409: ErrorResponse -- Instance already stopped 502: ErrorResponse -- Sidecar unavailable

GET /api/tenants/:tenantId/agents/instances/:instanceId/health

Get instance health

Returns liveness and readiness for a running instance. Liveness reflects whether the instance's sidecar connection is active. Readiness reflects whether the instance has an active event collector and can process work.

200: AgentHealth -- Health status 404: ErrorResponse -- Instance not found 410: ErrorResponse -- Instance stopped

GET /api/tenants/:tenantId/agents/instances/:instanceId/offerings

List instance offerings

Returns the offerings associated with the instance's agent definition. These represent the capabilities the instance can provide.

200: OfferingDetail[] -- List of offerings 404: ErrorResponse -- Instance not found

GET /api/tenants/:tenantId/agents/instances/:instanceId/events

SSE event stream

Server-Sent Events stream for agent events. Use POST .../messages for client-to-server messaging.

200: SSE stream -- SSE event stream 404: ErrorResponse -- Instance not found 410: ErrorResponse -- Instance stopped

POST /api/tenants/:tenantId/agents/instances/:instanceId/abort

Abort current operation

Aborts the agent's current inference or tool execution.

Body: unknown

204: (no content) -- Abort signal sent 404: ErrorResponse -- Instance not found 409: ErrorResponse -- Instance not running 502: ErrorResponse -- Sidecar unavailable

POST /api/tenants/:tenantId/agents/instances/:instanceId/mail

Send mail to the agent

Persists the user message as a mail record and dispatches it to the running agent. Returns JMAP Email-shaped response.

Body: SendMessage

201: MailResponse -- Mail sent 400: ErrorResponse -- Validation error 404: ErrorResponse -- Instance not found 409: ErrorResponse -- Instance not running 502: ErrorResponse -- Sidecar unavailable

GET /api/tenants/:tenantId/agents/instances/:instanceId/mail

List mail for an instance

Returns parsed JMAP Email objects in reverse chronological order. Cursor-paginated.

Query: cursor?, limit?

200: unknown -- List of mail 404: ErrorResponse -- Instance not found

GET /api/tenants/:tenantId/agents/instances/:instanceId/turns

List inference turns for an instance

Returns inference turns with their parts in reverse chronological order. Cursor-paginated.

Query: cursor?, limit?

200: unknown -- List of inference turns 404: ErrorResponse -- Instance not found

Approvals

GET /api/tenants/:tenantId/approvals

List pending approvals in the tenant

Returns pending approval requests for the authenticated user within this tenant.

200: ApprovalResponse[] -- List of approvals

GET /api/tenants/:tenantId/approvals/:approvalId

Get approval details

Returns the proposed action, context, originating agent, and session.

200: ApprovalResponse -- Approval details 404: ErrorResponse -- Approval not found

POST /api/tenants/:tenantId/approvals/:approvalId/approve

Approve an action

Approves the pending action. With scope 'once', the approval is one-time. With scope 'always', a persistent grant is created so the agent won't need to ask again.

Body: ApproveAction

200: ApprovalResponse -- Action approved 404: ErrorResponse -- Approval not found

POST /api/tenants/:tenantId/approvals/:approvalId/reject

Reject an action

Rejects the pending action. An optional message provides feedback to the agent.

Body: RejectAction

200: ApprovalResponse -- Action rejected 404: ErrorResponse -- Approval not found

Wallets

GET /api/tenants/:tenantId/wallets

List wallets in the tenant

Query: cursor?, limit?

200: unknown -- List of wallets

POST /api/tenants/:tenantId/wallets

Create a wallet

Creates a wallet with the specified payment backend and currency. Access for agents is managed through grants.

Body: CreateWallet

201: WalletResponse -- Wallet created 400: ErrorResponse -- Validation error

GET /api/tenants/:tenantId/wallets/:walletId

Get wallet details

Returns wallet details including current balance.

200: WalletResponse -- Wallet details 404: ErrorResponse -- Wallet not found

PATCH /api/tenants/:tenantId/wallets/:walletId

Update wallet config

Body: UpdateWallet

200: WalletResponse -- Wallet updated 404: ErrorResponse -- Wallet not found

DELETE /api/tenants/:tenantId/wallets/:walletId

Deactivate a wallet

204: (no content) -- Wallet deactivated 404: ErrorResponse -- Wallet not found

GET /api/tenants/:tenantId/wallets/:walletId/transactions

List transactions

Transaction history for a wallet. Filterable by agent, date range, and status.

Query: agentId?, startTime?, endTime?, status?: pending|completed|failed, cursor?, limit?

200: unknown -- List of transactions

Providers

GET /api/tenants/:tenantId/providers

List providers

Lists provider definitions for the tenant, including those inherited from ancestor tenants.

Query: inherited?: true|false, cursor?, limit?

200: unknown -- List of providers

POST /api/tenants/:tenantId/providers

Create a provider definition

Defines a new service provider for the tenant. The plugin field determines how Interchange integrates with the service.

Body: CreateProvider

201: ProviderResponse -- Provider created 400: ErrorResponse -- Validation error 409: ErrorResponse -- Provider name already exists in this tenant

GET /api/tenants/:tenantId/providers/:providerId

Get provider details

200: ProviderResponse -- Provider details 404: ErrorResponse -- Provider not found

PATCH /api/tenants/:tenantId/providers/:providerId

Update a provider definition

Only providers owned by this tenant can be updated.

Body: UpdateProvider

200: ProviderResponse -- Provider updated 404: ErrorResponse -- Provider not found

DELETE /api/tenants/:tenantId/providers/:providerId

Remove a provider definition

Only providers owned by this tenant can be removed.

204: (no content) -- Provider removed 404: ErrorResponse -- Provider not found

OAuth Clients

GET /api/tenants/:tenantId/oauth-clients

List OAuth client registrations

Lists OAuth client registrations for the tenant. Secrets are never returned.

Query: cursor?, limit?

200: unknown -- List of OAuth clients

POST /api/tenants/:tenantId/oauth-clients

Register an OAuth client

Registers an OAuth client (client_id/client_secret) for a provider. The provider must exist in the tenant or its ancestors.

Body: CreateOAuthClient

201: OAuthClientResponse -- OAuth client registered 400: ErrorResponse -- Validation error 404: ErrorResponse -- Provider not found 409: ErrorResponse -- OAuth client already exists for this provider in this tenant

GET /api/tenants/:tenantId/oauth-clients/:oauthClientId

Get OAuth client details

Returns OAuth client metadata. Secrets are never included.

200: OAuthClientResponse -- OAuth client details 404: ErrorResponse -- OAuth client not found

PATCH /api/tenants/:tenantId/oauth-clients/:oauthClientId

Update an OAuth client registration

Body: UpdateOAuthClient

200: OAuthClientResponse -- OAuth client updated 404: ErrorResponse -- OAuth client not found

DELETE /api/tenants/:tenantId/oauth-clients/:oauthClientId

Remove an OAuth client registration

204: (no content) -- OAuth client removed 404: ErrorResponse -- OAuth client not found

Credentials

GET /api/tenants/:tenantId/credentials

List credentials

Lists credential metadata. Secrets are never returned. Filterable by owner type.

Query: owner?: me|org|all, cursor?, limit?

200: unknown -- List of credentials

POST /api/tenants/:tenantId/credentials

Store a credential

Stores a credential (API key, OAuth token, etc.). The secret is stored securely and never returned in subsequent reads. A provider must be specified.

Body: CreateCredential

201: CredentialResponse -- Credential stored 400: ErrorResponse -- Validation error 404: ErrorResponse -- Provider not found 409: ErrorResponse -- Credential name already exists in this tenant

GET /api/tenants/:tenantId/credentials/resolve/:name

Resolve a credential by name

Resolves a credential by name, walking the tenant hierarchy. Returns metadata only (no secret). Useful for discovering which credential an agent would get.

200: CredentialResponse -- Credential metadata 404: ErrorResponse -- Credential not found

GET /api/tenants/:tenantId/credentials/:credentialId

Get credential metadata

Returns credential metadata. The secret is never included. Supports hierarchy-aware access.

200: CredentialResponse -- Credential metadata 404: ErrorResponse -- Credential not found

PATCH /api/tenants/:tenantId/credentials/:credentialId

Rotate or update a credential

Only credentials owned by this tenant can be updated.

Body: UpdateCredential

200: CredentialResponse -- Credential updated 404: ErrorResponse -- Credential not found

DELETE /api/tenants/:tenantId/credentials/:credentialId

Revoke a credential

Only credentials owned by this tenant can be revoked.

204: (no content) -- Credential revoked 404: ErrorResponse -- Credential not found

Observability

GET /api/tenants/:tenantId/agents/:agentId/logs

Get agent logs

Structured logs for an agent. Filterable by level and time range.

Query: level?: debug|info|warn|error, startTime?, endTime?

200: LogEntry[] -- Log entries 404: ErrorResponse -- Agent not found

GET /api/tenants/:tenantId/agents/:agentId/metrics

Get agent metrics

Returns throughput, latency, error rates, token usage, and cost metrics.

200: MetricsResponse -- Agent metrics 404: ErrorResponse -- Agent not found

GET /api/tenants/:tenantId/traces

Query distributed traces

Searches traces within the tenant. Filterable by agent, session, time range, and trace ID.

Query: agentId?, sessionId?, traceId?, startTime?, endTime?

200: SpanResponse[] -- List of traces

GET /api/tenants/:tenantId/traces/:traceId

Get a full trace

Returns all spans in a trace across agent boundaries.

200: TraceResponse -- Trace with spans 404: ErrorResponse -- Trace not found

Agent Data

GET /api/tenants/:tenantId/agents/:agentId/data

List files in agent working directory

200: FileEntry[] -- File listing 404: ErrorResponse -- Agent not found

GET /api/tenants/:tenantId/agents/:agentId/data/*

Read a file from agent storage

Reads a file by path from the agent's local storage.

200: FileContent -- File content 404: ErrorResponse -- File or agent not found

GET /api/tenants/:tenantId/agents/:agentId/history

List commits and checkpoints

Returns the agent's change history with commit messages and timestamps.

200: HistoryEntry[] -- History entries

GET /api/tenants/:tenantId/agents/:agentId/history/:ref

Show changes in a commit

Returns the files changed in a specific commit with additions/deletions counts.

200: CommitDetail -- Commit details 404: ErrorResponse -- Commit not found

GET /api/tenants/:tenantId/agents/:agentId/branches

List branches

Lists branches in the agent's data repository.

200: BranchInfo[] -- List of branches

POST /api/tenants/:tenantId/agents/:agentId/history/:ref/restore

Restore agent data to a previous state

Restores the agent's working directory to the state at the specified commit.

204: (no content) -- Data restored 404: ErrorResponse -- Commit not found

Sidecars

POST /api/sidecars

Register or update a sidecar

Upserts a sidecar record. If an id is provided and already exists, the record is updated. Used for idempotent sidecar registration by a known stable identifier.

Body: CreateSidecar

201: SidecarResponse -- Sidecar registered

GET /api/sidecars

List all sidecars

200: SidecarResponse[] -- List of sidecars

GET /api/sidecars/:id

Get a sidecar by ID

200: SidecarResponse -- Sidecar detail 404: ErrorResponse -- Sidecar not found

DELETE /api/sidecars/:id

Deregister a sidecar

204: (no content) -- Sidecar deregistered 404: ErrorResponse -- Sidecar not found

POST /api/sidecars/:id/heartbeat

Record a sidecar heartbeat

Updates the sidecar's last heartbeat timestamp and sets status to online.

204: (no content) -- Heartbeat recorded 404: ErrorResponse -- Sidecar not found

Type Reference

AgentHealth

{ liveness: "ok" | "unhealthy", readiness: "not_ready" | "ok" | "unhealthy", lastCheckedAt?: string | null } Source: packages/types/src/agents.ts

AgentInstanceResponse

{ address: string, agentId: string, agentName: string, createdAt: string, id: string, status: "deployed" | "error" | "running" | "stopped" | "updating", tenantId: string, updatedAt: string, endedAt?: string | null, kernelId?: string | null, publicKey?: string | null, sidecarId?: string | null } Source: packages/types/src/agents.ts

AgentResponse

{ createdAt: string, currentVersion: string, id: string, name: string, status: "deployed" | "stopped", tenantId: string, updatedAt: string, capabilities?: { [string]: unknown }, contextConfig?: { [string]: unknown }, creatorPrincipalId?: string | null, credentialRequirements?: { providerName: string, source: "creator" | "invoker" | "tenant", name?: string, scopes?: string[] }[], description?: string | null, grantRequirements?: { action: string, resource: string, source: "creator" | "invoker", conditions?: { [string]: unknown } | null, effect?: "allow" | "ask" | "deny" }[], initialState?: { [string]: unknown }, modelConfig?: { [string]: unknown }, roles?: { id: string, name: string }[], skills?: { [string]: unknown }, systemPrompt?: string | null } Source: packages/types/src/agents.ts

creatorPrincipalId: Identifies the definition author's principal (definitions have no principalId of their own). Used for resolving creator-sourced grant and credential requirements.

ApprovalResponse

{ action: string, agentId: string, createdAt: string, id: string, principalId: string, resource: string, sessionId: string, status: "approved" | "pending" | "rejected", tenantId: string, context?: { [string]: unknown } | null, resolvedAt?: string | null } Source: packages/types/src/approvals.ts

sessionId: Internal FK to the session channel. The approval was created during an instance's execution; the instance ID can be resolved via the session relationship.

ApprovalSummary

{ action: string, agentId: string, agentName: string, createdAt: string, id: string, resource: string, sessionId: string, tenantId: string, tenantName: string } Source: packages/types/src/me.ts

sessionId: Internal FK to the session channel. The instance ID can be resolved via the session relationship.

ApproveAction

{ scope: "always" | "once" } Source: packages/types/src/approvals.ts

BranchInfo

{ name: string, isCurrent?: boolean, lastCommitAt?: string | null, lastCommitMessage?: string | null, lastCommitRef?: string | null } Source: packages/types/src/agent-data.ts

CommitDetail

{ author: string, changes: { path: string, status: "added" | "deleted" | "modified", additions?: number, deletions?: number }[], message: string, ref: string, timestamp: string } Source: packages/types/src/agent-data.ts

CreateAgent

{ name: string, capabilities?: { [string]: unknown }, contextConfig?: { [string]: unknown }, credentialRequirements?: { providerName: string, source: "creator" | "invoker" | "tenant", name?: string, scopes?: string[] }[], description?: string, grantRequirements?: { action: string, resource: string, source: "creator" | "invoker", conditions?: { [string]: unknown } | null, effect?: "allow" | "ask" | "deny" }[], initialState?: { [string]: unknown }, modelConfig?: { [string]: unknown }, roleIds?: string[], skills?: { [string]: unknown }, systemPrompt?: string } Source: packages/types/src/agents.ts

grantRequirements: A grant requirements manifest, not live grants. Each entry declares a resource, action, and source (creator or invoker). The control plane resolves these requirements at each agent launch against the current authority of the creator and invoker.

CreateAgentInstance

{ agentId: string, invokerGrants?: { action: string, resource: string, conditions?: { [string]: unknown } | null, effect?: "allow" | "ask" | "deny" }[] } Source: packages/types/src/agents.ts

invokerGrants: Capabilities the invoker is willing to delegate to the agent, resolved against the invoker's own authority at launch. These are materialized as grants on the agent principal in addition to any grants from the definition's own requirements.

CreateCredential

{ name: string, providerId: string, secret: string, type: "api_key" | "certificate" | "oauth_token" | "other", description?: string, expiresAt?: string, metadata?: { [string]: unknown }, oauthClientId?: string, principalId?: string, refreshSecret?: string, scopes?: string[] } Source: packages/types/src/credentials.ts

CreateFederationTrust

{ direction: "bilateral" | "inbound" | "outbound", targetTenantId: string } Source: packages/types/src/tenants.ts

CreateGrant

{ action: string, effect: "allow" | "ask" | "deny", origin: "creator" | "invoker" | "role" | "system", resource: string, conditions?: { [string]: unknown } | null, expiresAt?: string | null, principalId?: string | null, roleId?: string | null } Source: packages/types/src/grants.ts

CreateOAuthClient

{ clientId: string, clientSecret: string, name: string, providerId: string, defaultScopes?: string[], metadata?: { [string]: unknown }, redirectUris?: string[] } Source: packages/types/src/oauth-clients.ts

CreateOffering

{ agentId: string, name: string, description?: string, pricing?: { base?: { amount: string, currency: string }, bounds?: { max?: string, min?: string }, methods?: string[], negotiable?: boolean }, schema?: { [string]: unknown } } Source: packages/types/src/offerings.ts

CreateProvider

{ name: string, plugin: string, authorizationUrl?: string, metadata?: { [string]: unknown }, scopes?: string[], tokenUrl?: string, userInfoUrl?: string } Source: packages/types/src/providers.ts

CreateRole

{ name: string, description?: string } Source: packages/types/src/roles.ts

CreateSidecar

{ url: string, id?: string >= 1, status?: "error" | "offline" | "online" } Source: packages/types/src/sidecars.ts

Register or update a sidecar. The id field supports idempotent registration by a known stable identifier; if omitted, the server generates one.

CreateTenant

{ name: string, slug: string, parentId?: string | null } Source: packages/types/src/tenants.ts

CreateWallet

{ backendType: "credits" | "crypto" | "fiat", currency: string, name: string, config?: { [string]: unknown } } Source: packages/types/src/wallets.ts

CredentialResponse

{ createdAt: string, id: string, name: string, providerId: string, status: "active" | "error" | "expired" | "revoked", tenantId: string, type: "api_key" | "certificate" | "oauth_token" | "other", updatedAt: string, description?: string | null, expiresAt?: string | null, metadata?: { [string]: unknown } | null, oauthClientId?: string | null, principalId?: string | null, scopes?: string[] | null } Source: packages/types/src/credentials.ts

ErrorResponse

{ error: { code: string, message: string } } Source: packages/types/src/common.ts

EvaluateRequest

{ action: string, resource: string } Source: packages/types/src/grants.ts

EvaluateResult

{ effect: "allow" | "ask" | "deny", matchingGrants: { action: string, effect: "allow" | "ask" | "deny", id: string, origin: "creator" | "invoker" | "role" | "system", resource: string, specificity?: number }[] } Source: packages/types/src/grants.ts

FederationTrust

{ createdAt: string, direction: "bilateral" | "inbound" | "outbound", tenantDomain: string, tenantId: string, tenantName: string } Source: packages/types/src/tenants.ts

FileContent

{ content: string, path: string, encoding?: "base64" | "utf-8" } Source: packages/types/src/agent-data.ts

FileEntry

{ path: string, type: "directory" | "file", modifiedAt?: string | null, size?: number | null } Source: packages/types/src/agent-data.ts

GrantResponse

{ action: string, createdAt: string, effect: "allow" | "ask" | "deny", id: string, origin: "creator" | "invoker" | "role" | "system", resource: string, tenantId: string, updatedAt: string, conditions?: { [string]: unknown } | null, expiresAt?: string | null, principalId?: string | null, principalName?: string | null, roleId?: string | null, roleName?: string | null } Source: packages/types/src/grants.ts

HistoryEntry

{ author: string, message: string, ref: string, timestamp: string, filesChanged?: number } Source: packages/types/src/agent-data.ts

InviteMember

{ email: string, roleId?: string } Source: packages/types/src/principals.ts

LogEntry

{ level: "debug" | "error" | "info" | "warn", message: string, timestamp: string, metadata?: { [string]: unknown } | null } Source: packages/types/src/observability.ts

MailResponse

{ attachments: { blobId: string, name: string | null, size: number, type: string }[], bodyValues: { [string]: unknown }, direction: "inbound" | "outbound", from: { email: string, name: string | null }[], headers: { [string]: string }, htmlBody: { partId: string, type: string }[], id: string, instanceId: string | null, receivedAt: string, sentAt: string | null, sessionId: string, status: "delivered" | "pending", subject: string | null, textBody: { partId: string, type: string }[], to: { email: string, name: string | null }[] } Source: packages/types/src/sessions.ts

sessionId: Internal session channel identifier, not a user-facing session resource.

MetricsResponse

{ agentId: string, avgLatencyMs?: number, cost?: string, errorRate?: number, messageCount?: number, tokenUsage?: { input?: number, output?: number, total?: number } } Source: packages/types/src/observability.ts

ModelInfo

{ id: string, name: string, providerId: string, capabilities?: string[], description?: string | null, limits?: { context?: number, output?: number }, pricing?: { cacheRead?: string, cacheWrite?: string, input?: string, output?: string } } Source: packages/types/src/models.ts

OAuthClientResponse

{ createdAt: string, id: string, name: string, providerId: string, tenantId: string, updatedAt: string, defaultScopes?: string[] | null, metadata?: { [string]: unknown } | null, redirectUris?: string[] | null } Source: packages/types/src/oauth-clients.ts

OfferingDetail

{ agentId: string, agentName: string, id: string, name: string, tenantId: string, description?: string | null, pricing?: { base?: { amount: string, currency: string }, bounds?: { max?: string, min?: string }, methods?: string[], negotiable?: boolean }, schema?: { [string]: unknown } | null } Source: packages/types/src/offerings.ts

PrincipalResponse

{ createdAt: string, displayName: string, id: string, kind: "agent" | "user", refId: string, roles: { id: string, name: string }[], status: "active" | "deactivated" | "invited" | "suspended", tenantId: string, updatedAt: string, email?: string } Source: packages/types/src/principals.ts

ProviderResponse

{ createdAt: string, id: string, name: string, plugin: string, tenantId: string, updatedAt: string, authorizationUrl?: string | null, metadata?: { [string]: unknown } | null, scopes?: string[] | null, tokenUrl?: string | null, userInfoUrl?: string | null } Source: packages/types/src/providers.ts

RejectAction

{ message?: string } Source: packages/types/src/approvals.ts

RoleResponse

{ createdAt: string, id: string, isSystem: boolean, name: string, tenantId: string, updatedAt: string, description?: string | null } Source: packages/types/src/roles.ts

RollbackRequest

{ version: string } Source: packages/types/src/agents.ts

SendMessage

{ content: string, attachments?: { type: string, url: string, mimeType?: string }[] } Source: packages/types/src/sessions.ts

SessionSummary

{ agentId: string, agentName: string, createdAt: string, id: string, status: "ended" | "ending" | "idle", tenantId: string, tenantName: string, lastActivityAt?: string | null } Source: packages/types/src/me.ts

SidecarResponse

{ createdAt: string, id: string, lastHeartbeat: string | null, status: "error" | "offline" | "online", updatedAt: string, url: string } Source: packages/types/src/sidecars.ts

SpanResponse

{ name: string, spanId: string, startTime: string, traceId: string, agentId?: string | null, attributes?: { [string]: unknown } | null, durationMs?: number | null, endTime?: string | null, parentSpanId?: string | null, status?: "error" | "ok" } Source: packages/types/src/observability.ts

TenantResponse

{ createdAt: string, domain: string, id: string, name: string, slug: string, updatedAt: string, config?: { [string]: unknown }, parentId?: string | null } Source: packages/types/src/tenants.ts

TraceResponse

{ spans: { name: string, spanId: string, startTime: string, traceId: string, agentId?: string | null, attributes?: { [string]: unknown } | null, durationMs?: number | null, endTime?: string | null, parentSpanId?: string | null, status?: "error" | "ok" }[], traceId: string } Source: packages/types/src/observability.ts

UpdateAgent

{ capabilities?: { [string]: unknown }, contextConfig?: { [string]: unknown }, credentialRequirements?: { providerName: string, source: "creator" | "invoker" | "tenant", name?: string, scopes?: string[] }[], description?: string, grantRequirements?: { action: string, resource: string, source: "creator" | "invoker", conditions?: { [string]: unknown } | null, effect?: "allow" | "ask" | "deny" }[], initialState?: { [string]: unknown }, modelConfig?: { [string]: unknown }, name?: string, roleIds?: string[], skills?: { [string]: unknown }, systemPrompt?: string } Source: packages/types/src/agents.ts

UpdateCredential

{ description?: string, expiresAt?: string | null, metadata?: { [string]: unknown }, name?: string, refreshSecret?: string | null, scopes?: string[] | null, secret?: string, status?: "active" | "error" | "expired" | "revoked" } Source: packages/types/src/credentials.ts

UpdateGrant

{ conditions?: { [string]: unknown } | null, effect?: "allow" | "ask" | "deny", expiresAt?: string | null } Source: packages/types/src/grants.ts

UpdateOAuthClient

{ clientId?: string, clientSecret?: string, defaultScopes?: string[] | null, metadata?: { [string]: unknown } | null, name?: string, redirectUris?: string[] | null } Source: packages/types/src/oauth-clients.ts

UpdateOffering

{ description?: string, name?: string, pricing?: { base?: { amount: string, currency: string }, bounds?: { max?: string, min?: string }, methods?: string[], negotiable?: boolean }, schema?: { [string]: unknown } } Source: packages/types/src/offerings.ts

UpdatePrincipal

{ status: "active" | "deactivated" | "suspended" } Source: packages/types/src/principals.ts

UpdateProvider

{ authorizationUrl?: string | null, metadata?: { [string]: unknown } | null, name?: string, plugin?: string, scopes?: string[] | null, tokenUrl?: string | null, userInfoUrl?: string | null } Source: packages/types/src/providers.ts

UpdateRole

{ description?: string, name?: string } Source: packages/types/src/roles.ts

UpdateTenant

{ config?: { [string]: unknown }, name?: string } Source: packages/types/src/tenants.ts

UpdateWallet

{ config?: { [string]: unknown }, name?: string } Source: packages/types/src/wallets.ts

UserProfile

{ createdAt: string, email: string, emailVerified: boolean, id: string, name: string, updatedAt: string, image?: string | null } Source: packages/types/src/me.ts

WalletResponse

{ backendType: "credits" | "crypto" | "fiat", balance: string, createdAt: string, currency: string, id: string, name: string, tenantId: string, updatedAt: string, config?: { [string]: unknown } } Source: packages/types/src/wallets.ts