Skip to main content
Audience: developers upgrading @beeos-ai/sdk (TypeScript) or github.com/beeos-ai/sdk-go (Go) between major or minor versions. This guide is wire-only — the codegen tooling (openapi-generator-cli + the configs in sdks/openapi-sdk/) is not documented here, only the changes consumers see.
Each section covers one upgrade path. Within a section the recipes are stable: TS first, then Go, then “if you wrote custom HTTP code, do this instead”. Cross-link to docs/CHANGELOG.md for the full machine- readable list of changes; this file is the human walkthrough. Both SDKs share one version line. When you bump the TS package you MUST bump the Go module to the same tag in the same release. Don’t mix them — that’s how you end up calling a route on one SDK that doesn’t exist on the other.

Quick choose-your-path


1. 0.3.x0.4.x

0.4 is the first time the SDKs were stamped from the decoupled openapi-gateway BFF (ADR-001). The wire is almost a superset of 0.3, with one breaking change:

1.1 BREAKING — SendMessageResponse.offset removed

The field was a misleading placeholder. The actual offset is opaque inside the since cursor returned by the same response. TS — before:
TS — after:
Go — before:
Go — after:

1.2 Added — idempotency_key on invoke

Optional. Old callers keep working; new callers should set it on any operation that retries on transient failure:
If the same key arrives twice within the dedup window, the second call returns the first call’s reply. See Calling Agents § Idempotency.

1.3 Added — TaskResponse.truncated

Optional boolean. If the task’s event log exceeded the 1 000-message scan cap, this is true and the returned event list may not be exhaustive. Old code can ignore the field; new code should display a “scroll back further” UI hint:

1.4 Added — PushNotificationConfig.protocol_filter

When you register a webhook via the OpenAPI surface, the gateway stamps protocol_filter="openapi" automatically. When you register via A2A’s pushNotificationConfig/set, it gets protocol_filter="a2a". Lets you have one receiver URL behind multiple filtered subscriptions (e.g. only OpenAPI events, not A2A federation events). No breaking change — old clients ignored this field; new clients can use it for filtering.

2. 0.6.00.6.1

TaskStatus success now matches the server’s canonical wire value:
Update polling and terminal-state comparisons to use completed. This change only applies to Platform Task status. Runtime Operation outcomes and webhook delivery status have separate enums and continue to use succeeded.

3. 0.5.00.6.0

This release has no wire-level migration. Existing generated-client calls continue to work. You can adopt the new task facade incrementally:
For TypeScript consumers, Node.js 20 or newer is now required. Both ESM and CommonJS remain supported through explicit package exports. Go callers can adopt NewClient(ClientOptions{...}) while retaining direct access to the generated client through Client.API.

4. 0.4.x0.5.0

The entries below shipped together in 0.5.0. None are breaking. Set secret when registering a webhook and every delivery ships an X-BeeOS-Signature header. The wire response only returns has_secret: true; the raw secret is never echoed. TS — register with signing:
Verify on receipt (Node):
See Webhooks § 6 HMAC signing for the Python variant and the full delivery contract.

4.2 Webhook delivery audit log + manual replay

Two new endpoints:
  • GET .../webhooks/{webhookId}/deliveries?limit=50 — last N per-attempt rows.
  • POST .../webhooks/{webhookId}/deliveries/{deliveryId}/redeliver — re-queue a failed / dead_letter row immediately.

4.3 GET /api/v1/tasks — cross-agent inbox

Previously you had to call GET /agents/{id}/tasks once per agent to assemble a multi-agent inbox. Now:
Pages with since (offset cursor).

4.4 attachments[].file_id on invoke / tasks / conversations

Replace the old “stuff the binary in message” workflow with:
Old “no attachments” callers keep working — the field is optional.

4.5 PATCH /api/v1/agents/{agentId}

Owner-only update of visibility and mcp_enabled (whitelist). Other fields (name, description, …) are still synced by the agent process via POST /api/v1/agents/sync — patching them here would be silently overwritten, so the SDK doesn’t let you.

4.6 Wire-error envelope tightened

All 4xx / 5xx now follow the canonical envelope (type, code, message, param?, request_id). Old code that only inspected the HTTP status keeps working; new code should branch on error.code. See Error Reference.

4.7 Scope vocabulary removed (v1.1.0)

The oag_ User API Key per-route scope gate (agents:read, agents:write, tasks:read, tasks:write, files:read, files:write, instances:read, instances:write, plus the admin:* wildcard) has been removed entirely. Existing keys automatically gain full owner-level access and do not need to be re-issued; cross-tenant access is denied by owner-ACL inside the handlers, not by per-route scopes. What this means for SDK migrations:
  • Drop scopes from createAPIKey / POST /api-keys calls. The field is silently ignored on the wire during the rolling deploy window; remove it at your earliest convenience so callers don’t carry stale assumptions.
  • Fold insufficient_scope (403) into your generic 403 / forbidden handler. The code is no longer emitted, but existing branches matching on it will simply become dead — safe to delete in the same change.
  • Remove scope badges / pickers from your UI. Server-side responses no longer carry a scopes field on APIKey or APIKeyCreateResult.

4.8 timeout_ms clamp on invoke

The blocking-invoke timeout is clamped to [100, 115_000] ms server-side. Passing timeoutMs: 200_000 no longer hangs your connection past the gateway limit — it’s clamped to 115s and returns service_timeout at the clamp. New code should pick a realistic value; old code that was intending a hang will now error out promptly.

5. Hand-rolled HTTP → SDK

If you’ve been calling https://openapi.beeos.ai/api/v1/... with fetch / axios / net/http directly, the migration is mostly mechanical:
  1. npm install @beeos-ai/sdk@latest (or go get github.com/beeos-ai/sdk-go@latest).
  2. Construct one Configuration with your base URL and Authorization: Bearer <oag_… | jwt>:
  3. Replace each route with the corresponding <Tag>Api method. The mapping is one-to-one with the operationId field in backend/openapi/beeos-platform-v1.yaml.
  4. Error handling. The SDK throws on non-2xx. Catch and inspect err.response?.error?.code:
  5. SSE. The TS SDK does NOT abstract SSE today. For streaming endpoints, keep your hand-rolled EventSource and point it at the URL returned by the SDK’s “build URL” helper, OR use Accept: text/event-stream directly on the underlying fetch. See Streaming.
  6. Idempotency. The SDK does NOT auto-set idempotency_key; pass it explicitly on any retry path.

6. 0.2.x0.4.x

0.2 predates the OpenAPI Gateway BFF decoupling (ADR-001). The SDK was generated from the main Gateway’s swagger and the route set was broader (and inconsistent — half the routes were user-only, half were public). Recommended path: bump straight to 0.4.x. The route names that survived are unchanged; routes that were removed are ones that should never have been part of the public SDK in the first place (admin endpoints, internal control-plane calls). If you have stuck callers on 0.2.x:
  1. First, audit which routes you actually use. Most consumers were calling 3-5 endpoints out of the 50+ surface.
  2. Then, check each against backend/openapi/beeos-platform-v1.yaml. If it’s there, it’s still supported. If it isn’t, you were on a non-contract route — open an issue and we’ll add it (or point you at the right surface).
  3. Finally, follow § 1 + § 2 above for the wire deltas.
There is no programmatic migration tool — the changes are small enough that find/replace + a unit-test pass covers it.

See also