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.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
| You’re on | Read this section |
|---|---|
0.3.x and earlier (pre-webhook-signing) | § 1 — 0.3 → 0.4 and § 2 — 0.4 → unreleased |
0.4.x (today’s published) | § 2 — 0.4 → unreleased |
Hand-rolled fetch/net/http directly against openapi.beeos.ai | § 3 — hand-rolled HTTP → SDK |
Migrating off 0.2.x (pre-BFF decoupling) | § 4 — 0.2.x → 0.4.x |
1. 0.3.x → 0.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:
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:
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.4.x → Unreleased (current main)
The Unreleased entries below ship together in the next minor
release. None are breaking.
2.1 Webhook HMAC signing — opt-in but recommended
Setsecret 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:
2.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 afailed/dead_letterrow immediately.
2.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:
since (offset cursor).
2.4 attachments[].file_id on invoke / tasks / conversations
Replace the old “stuff the binary in message” workflow with:
2.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.
2.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.
2.7 Scope vocabulary removed (v1.1.0)
Theoag_ 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
scopesfromcreateAPIKey/POST /api-keyscalls. 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 /forbiddenhandler. 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
scopesfield onAPIKeyorAPIKeyCreateResult.
2.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.
3. Hand-rolled HTTP → SDK
If you’ve been callinghttps://openapi.beeos.ai/api/v1/...
with fetch / axios / net/http directly, the migration is
mostly mechanical:
npm install @beeos-ai/sdk@latest(orgo get github.com/beeos-ai/sdk-go@latest).- Construct one
Configurationwith your base URL andAuthorization: Bearer <oag_… | jwt>: - Replace each route with the corresponding
<Tag>Apimethod. The mapping is one-to-one with theoperationIdfield inbackend/openapi/beeos-platform-v1.yaml. - Error handling. The SDK throws on non-2xx. Catch and
inspect
err.response?.error?.code: - SSE. The TS SDK does NOT abstract SSE today. For
streaming endpoints, keep your hand-rolled
EventSourceand point it at the URL returned by the SDK’s “build URL” helper, OR useAccept: text/event-streamdirectly on the underlyingfetch. See Streaming. - Idempotency. The SDK does NOT auto-set
idempotency_key; pass it explicitly on any retry path.
4. 0.2.x → 0.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:
- First, audit which routes you actually use. Most consumers were calling 3-5 endpoints out of the 50+ surface.
- 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). - Finally, follow § 1 + § 2 above for the wire deltas.
See also
docs/CHANGELOG.md— the canonical list of what changed in each version.sdks/openapi-sdk/generate.sh— where the version stamps live.backend/docs/adr/001-openapi-gateway-bff.md— the rationale for the0.4.x“fresh start”.docs/reference/errors.md— the fullcodetable for typed error handling.docs/guides/auth-api-keys.md— credential matrix; covers the v1.1.0 scope removal in detail.