GET /v1/actions/search takes words and returns references ranked for agents:

bash
curl -s -G https://beta-api.b3os.org/v1/actions/search \ -H "Authorization: Bearer $B3OS_API_KEY" \ --data-urlencode "q=create a github issue" -d limit=5
json
{ "object": "list", "data": [ { "ref": "io.b3os/github/create-issue@1.2.0", "pack": "io.b3os/github", "title": "Create an issue", "description": "Open an issue in a repository. Returns the issue number and URL.", "effects": "write", "connections": ["api"], "mcp_name": "github__create-issue", "score": 0.92 } ], "next_cursor": null}

The values are illustrative. Narrow the search with pack (io.b3os/github) or effects (read, for example).

Describe

GET /v1/actions/describe?ref=io.b3os/github/create-issue@1 returns everything needed to call the action: input_schema and output_schema (JSON Schema 2020-12), the effect class, MCP annotations, the action as an MCP tool definition, and the connections it needs, each with its key and type (bearer, api_key, basic or oauth2). A major version such as @1 resolves to the newest matching release, and the response names the exact one.

Call

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{"ref": "io.b3os/github/create-issue@1", "input": {"owner": "acme", "repo": "web", "title": "Checkout button misaligned on mobile"}, "connections": {"api": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}}'
json
{ "object": "action_result", "ref": "io.b3os/github/create-issue@1.2.0", "output": { "number": 1423, "url": "https://github.com/acme/web/issues/1423" }, "upstream_status": 201, "timing": { "validate_ms": 0.03, "inject_ms": 0.02, "upstream_ms": 412.6, "map_ms": 0.04, "total_ms": 412.8 }}

The values are illustrative. ref is the exact version that ran. timing separates B3OS's own work (validating the input, injecting the credential, mapping the response) from the time the upstream service took.

Connections

connections maps each of the action's connection keys to a vault connection ID. Leave a key out and B3OS uses your project's only connection for that pack and key; with several, name one. Naming a connection needs vault:run on top of actions:run. Vault explains how to store one.

The credential is added at the egress proxy, only for the hosts the pack declares for that connection. The call fails with connection_required when the action needs a connection and none is available to the caller, and with connection_mismatch when the connection's type, pack or hosts do not fit the action.

Retries and idempotency

B3OS retries pure and read actions on its own. It never retries write or irreversible actions for you: send an Idempotency-Key with them, as above, so that your own retry after a timeout returns the stored result instead of acting twice. Packs that support it pass the key on to the service.

When it fails

CodeStatusMeaning
action_input_invalid422The input does not match the input schema; errors[] points at the field, such as /input/title
upstream_error502The service answered with an error. upstream_status has its status and pack_error the pack's reading of it
action_output_invalid502The service answered, but the result does not match the output schema; report it to the pack publisher
action_not_found, pack_not_found404No such action or pack on the node
connection_required422The action needs a credential you have not supplied or may not use

From routines and sandboxes

  • In a routine, an action is a step: uses: io.b3os/github/create-issue@1 with the input as with, and the connections bound with connections. A major version is pinned when the routine version is published. See definitions.
  • In a sandbox, grant actions:run and vault:run, and list the connections in api.connections; code inside then calls http://127.0.0.1:7700/v1/actions/call with no key, and the credential never enters the sandbox. See agents in sandboxes.
Ask a question... ⌘I