SDK

Agents

Everything you do to a customer's agent (create it, talk to it, configure it, and clean it up) is a method on maritime.agents.

Provision (get-or-create)

provision is idempotent on externalId: first call creates the agent, later calls return the same one. That makes it safe to run on every sign-in: you never double-create, and you never have to store Maritime's agent id. Use create instead if you want a hard failure when the name already exists.

const agent = await maritime.agents.provision({
  externalId: `customer_${user.id}`,
  name: `assistant-${user.id}`,
  template: 'openclaw',              // see /docs/frameworks
  instructions: 'You are a helpful assistant.',
  idleTtlSeconds: 3600,              // 0 = always-on
})

Chat

Send a message and wait for the reply. Sleeping agents wake automatically. Pass a conversationId to keep a thread. chat resolves with { response, error? }. It does not throw on a delivery failure (a still-deploying agent, an LLM error), so check error.

const { response, error } = await maritime.agents.chat(agent.id, 'What can you do?')
if (error) throw new Error(error)

// continue a thread:
await maritime.agents.chat(agent.id, 'And after that?', { conversationId: 'thread-1' })

Per-customer secrets & config

Give each customer's agent its own credentials and config as env vars. Secrets are encrypted at rest; changes reach a running container after a reload.

await maritime.agents.setEnv(agent.id, 'ACME_API_KEY', user.acmeKey, { secret: true })
await maritime.agents.setEnv(agent.id, 'ACME_REGION', 'us-east', { secret: false })
await maritime.agents.reloadEnv(agent.id)   // push into the running container

// read them back (secret values come back masked):
for (const v of await maritime.agents.listEnv(agent.id)) {
  console.log(v.key, v.isSecret ? '(secret)' : v.value)
}

Lifecycle, logs & teardown

Agents sleep and wake on their own, but you can drive the lifecycle directly. Find an agent by your own id, read its logs, or tear it all down when a customer leaves.

const [agent] = await maritime.agents.list({ externalId: `customer_${user.id}` })

await maritime.agents.logs(agent.id, { limit: 100, level: 'error' })

await maritime.agents.sleep(agent.id)     // cheapest resting state
await maritime.agents.start(agent.id)     // wake it
await maritime.agents.restart(agent.id)

await maritime.agents.delete(agent.id)    // container + volume + network

Handling errors

Every failure is a typed subclass of MaritimeError. Catch the base to catch them all, or narrow by type.

import { MaritimeConflictError, MaritimePaymentRequiredError } from 'maritime-sdk'

try {
  await maritime.agents.create({ name: 'dupe', template: 'openclaw' })
} catch (err) {
  if (err instanceof MaritimeConflictError) {
    // 409: an agent with that name already exists
  } else if (err instanceof MaritimePaymentRequiredError) {
    // 402: your Maritime wallet needs funding
  } else {
    throw err
  }
}

The full error hierarchy (MaritimeAuthError, MaritimeNotFoundError, MaritimeRateLimitError, MaritimeConnectionError) is in the API reference.