Get a pack manifest
Returns the exact `b3pack.json` of one pack version, as published and signed.
GET
/v1/actions/packs/{namespace}/{name}/versions/{version}/manifest
Returns the exact `b3pack.json` of one pack version, as published and signed.
Authentication
Bearer Token (b3os_sk_ API key or b3os_pat_ token) API Key (cookie: __Host-b3os_session)
Path Parameters
namespace
string
required
path
Reverse-DNS publisher namespace, such as `io.b3os`.
Example:
"io.b3os"name
string
required
path
Pack name within the namespace, such as `github`.
Example:
"github"version
string
required
path
Exact semantic version, without build metadata (b3pack's `semver`).
Example:
"1.0.0"Responses
200
The manifest.
application/json$schema
string (uri)
Optional pointer to this schema for editors. Ignored by the runtime.
pack
string
REQUIRED
Pack id <namespace>/<name>, e.g. io.b3os/github. Action refs are <namespace>/<name>/<action>@<semver>.
version
string
REQUIRED
Semantic version 2.0.0 without build metadata (two versions that differ only in build metadata would be the same release).
title
string
REQUIRED
description
string
REQUIRED
publisher
object
REQUIRED
Who publishes the pack. id must equal the namespace part of pack (registry check). Verification status lives in the registry record, never in the manifest, so a manifest cannot claim to be verified.
id
string
REQUIRED
Reverse-DNS publisher namespace with at least one dot, lowercase: io.b3os, com.example, io.github.acme.
name
string
REQUIRED
url
string (uri)
email
string (email)
license
string
REQUIRED
SPDX license expression, e.g. MIT, Apache-2.0, or LicenseRef-<name>.
facets
object
Discovery facets (research 12.12). Free kebab-case values; the registry curates the displayed set.
domain
string[]
Array of:
string
assetClass
string[]
Array of:
string
chains
string[]
Array of:
string
icons
object[]
MCP-style icons. src is a bundle-relative path under assets/ or an https URL.
Array of:
src
string
REQUIRED
mimeType
unknown
Enum:
image/svg+xml, image/png, image/webpsizes
string[]
Array of:
string
engine
string
REQUIRED
Pack runtime API the pack needs, as a caret range (npm and Cargo read it the same way). The v1 runtime is 1.0.0, so packs declare ^1 or ^1.0.
connections
object
Credentials and configuration the pack's actions and triggers can use, keyed by a connection key that templates reference as connections.<key>. A customer binds each key to a vault connection (conn_). Secrets are injected at the egress layer and never reach templates, fixtures or T1 code.
egress
object[]
Pack-wide egress ceiling: every outbound request from any action or trigger must match one entry. Actions may narrow it with their own egress list. Enforced by the b3os-core egress guard (ARCHITECTURE 4.4); a host diff between versions counts as a major change.
Array of:
host
string
REQUIRED
Lowercase host. Exact (api.github.com), wildcard (*.slack.com matches any name below slack.com but not slack.com itself), or * for any public host. * is first-party only and never receives injected credentials. IP literals are not allowed; the egress guard resolves names and denies private ranges either way.
ports
integer[]
Allowed destination ports. Default [443].
Array of:
integer
schemes
unknown[]
Allowed URL schemes. Default ["https"]; plain http must be listed explicitly.
Array of:
unknown
actions
object[]
REQUIRED
Array of:
key
string
REQUIRED
Action or trigger key, kebab-case, unique within the pack.
title
string
REQUIRED
description
string
REQUIRED
inputSchema
object | boolean & object
REQUIRED
A JSON Schema 2020-12 document whose top level describes an object (MCP requires object-typed inputSchema and outputSchema). Objects should be closed (additionalProperties false) unless declared open (research 12.4). x-b3-* keywords (x-b3-widget, x-b3-semantic, x-b3-options, ...) are allowed as annotations and ignored by validation.
type
unknown
REQUIRED
Enum:
objectoutputSchema
object | boolean & object
REQUIRED
A JSON Schema 2020-12 document whose top level describes an object (MCP requires object-typed inputSchema and outputSchema). Objects should be closed (additionalProperties false) unless declared open (research 12.4). x-b3-* keywords (x-b3-widget, x-b3-semantic, x-b3-options, ...) are allowed as annotations and ignored by validation.
type
unknown
REQUIRED
Enum:
objecteffects
object
REQUIRED
The single source for MCP annotations, approval UI, retries and routine durability (research 12.3). readOnlyHint = class in {pure, read}; destructiveHint = class == irreversible; openWorldHint = effective egress is non-empty. The runtime retries only pure and read calls and never auto-retries irreversible ones.
class
unknown
REQUIRED
Enum:
pure, read, write, irreversibleimpl
object | object
REQUIRED
How the action runs. http = T0, declarative HTTP inside b3osd. js = T1, a first-party ES module run by the actions-js sidecar (packages/spec/sidecars/actions-js.md).
One of:
Option 1
kind
unknown
REQUIRED
Enum:
httprequest
object
REQUIRED
T0 request template. CEL context: input (validated input with schema defaults applied) and connections.<key>.params. In url, every expression that is not the whole string is percent-encoded with the RFC 3986 unreserved set (like encodeURIComponent); a whole-string url expression must yield an absolute URL and is used as is. The final URL must match the effective egress list; a templated host label may only produce [a-z0-9-] and must match a wildcard egress entry.
method
unknown
REQUIRED
Enum:
GET, HEAD, POST, PUT, PATCH, DELETEurl
string
REQUIRED
query
object
Query parameters appended to url, form-encoded. Value results: string, int, double and bool are stringified; null omits the parameter; a list repeats the parameter once per element; a map is an error.
headers
object
Request headers. A null result omits the header; a value containing CR or LF fails the call. Not allowed: Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Proxy-*, and any header a required connection injects.
body
unknown
Request body template. Not allowed with GET or HEAD.
bodyEncoding
unknown
json (default): the evaluated body is serialized as JSON with Content-Type application/json. form: the body must evaluate to a flat map; it is sent as application/x-www-form-urlencoded with the query rules above. text: the body must evaluate to a string; Content-Type defaults to text/plain;charset=utf-8.
Enum:
json, form, textresponse
object
Response handling. CEL context: input, connections, response {status: int, headers: map of lowercase name to string (repeated headers joined with ', '), body: parsed JSON or string}.
body
unknown
How to read the body. auto (default): JSON when Content-Type is application/json or ends in +json, otherwise text. json fails the call if the body is not JSON. text keeps a string.
Enum:
auto, json, textsuccess
string
Whether the call succeeded. Default ${{ response.status >= 200 && response.status < 300 }}.
map
unknown
Output template, evaluated on success. The result must validate against outputSchema. Default ${{ response.body }}.
errors
object[]
Evaluated in order when success is false; the first match decides the error. No match: code upstream_error, retryable when status is 429 or 5xx.
Array of:
...
Option 2
kind
unknown
REQUIRED
Enum:
jsentry
string
REQUIRED
Bundle-relative path of a self-contained ES module (bundled; no bare imports except node: built-ins the sidecar allows).
export
string
Exported async function to call. Default run.
requires
object
connections
string[]
Connection keys this action uses. Each must be declared in connections. For T0, every listed connection injects its credential into requests whose host matches its hosts.
Array of:
string
egress
object[]
Narrows the pack egress list for this action; each entry must be covered by a pack entry. Default: the pack list. An action with an empty effective list may not make network calls (only pure T1 transforms).
Array of:
host
string
REQUIRED
Lowercase host. Exact (api.github.com), wildcard (*.slack.com matches any name below slack.com but not slack.com itself), or * for any public host. * is first-party only and never receives injected credentials. IP literals are not allowed; the egress guard resolves names and denies private ranges either way.
ports
integer[]
Allowed destination ports. Default [443].
Array of:
integer
schemes
unknown[]
Allowed URL schemes. Default ["https"]; plain http must be listed explicitly.
Array of:
unknown
execution
object
timeoutMs
integer
Wall-clock budget per call, including upstream time. Default 10000 for http, 30000 for js. A caller's shorter deadline wins.
memoryMb
integer
T1 only: V8 old-generation limit of the worker running the call. Default 128.
idempotencyHeader
string
T0 write or irreversible only: header that carries the caller's idempotency key upstream (for example Idempotency-Key for Stripe). Absent means the upstream has no idempotency support.
annotations
object
MCP hints that effects cannot derive. readOnlyHint, destructiveHint and openWorldHint are always derived and may not be set here.
idempotentHint
boolean
examples
(object | object)[]
Array of:
One of:
Option 1
fixture
string
REQUIRED
Bundle-relative path of a fixture file (see $defs/fixture).
Option 2
title
string
input
object
REQUIRED
output
unknown
pricing
object
Publisher price on top of the platform's actions.call meter. v0.1 first-party packs are free. Amounts are decimal strings in USD to avoid float rounding.
model
unknown
REQUIRED
Enum:
free, per_callusd
string
mcp
object
name
string
MCP tool name override; must be unique in the pack.
expose
boolean
false keeps the action out of tools/list (still callable through actions_call). Default true.
triggers
object[]
Array of:
key
string
REQUIRED
Action or trigger key, kebab-case, unique within the pack.
title
string
REQUIRED
description
string
REQUIRED
kind
unknown
REQUIRED
Enum:
webhook, poll, scheduleconfigSchema
object | boolean & object
Per-subscription configuration, available to CEL as config. Default: an empty closed object.
eventSchema
object | boolean & object
REQUIRED
A JSON Schema 2020-12 document whose top level describes an object (MCP requires object-typed inputSchema and outputSchema). Objects should be closed (additionalProperties false) unless declared open (research 12.4). x-b3-* keywords (x-b3-widget, x-b3-semantic, x-b3-options, ...) are allowed as annotations and ignored by validation.
type
unknown
REQUIRED
Enum:
objectrequires
object
connections
string[]
Array of:
string
examples
object[]
Array of:
fixture
string
REQUIRED
Bundle-relative path of a fixture file (see $defs/fixture).
verify
object
Mandatory delivery verification (ARCHITECTURE 4.3). Signatures are compared in constant time over the raw request body bytes. Schemes: github: X-Hub-Signature-256 'sha256=<hex HMAC-SHA256(secret, body)>'. stripe: Stripe-Signature 't=<unix>,v1=<hex>' over '<t>.<body>' (any v1 may match). slack: X-Slack-Signature 'v0=<hex>' over 'v0:<X-Slack-Request-Timestamp>:<body>'. standard_webhooks: webhook-signature 'v1,<base64>' entries over '<webhook-id>.<webhook-timestamp>.<body>', secret is base64 after the whsec_ prefix. hmac_sha256: generic, and always timestamped: the header value is prefix plus the HMAC-SHA256 (hex or base64, per encoding) of '<value of timestampHeader>.<body>', and a delivery whose timestamp header is missing or not a Unix time is refused. Timestamped schemes (stripe, slack, standard_webhooks, hmac_sha256) reject deliveries more than toleranceS (at most 300 s, the same rule as routine webhooks) from the node clock. The node also remembers the verified signature of each accepted delivery with its dedupe key (73 h, up to 10,000 per subscription), so a delivery replayed with a different unsigned header (for example X-GitHub-Delivery, which github's dedupe key reads) is still a duplicate; github signs no timestamp, so outside that window such a replay is not refused.
scheme
unknown
REQUIRED
Enum:
github, stripe, slack, standard_webhooks, hmac_sha256secret
object
REQUIRED
from
unknown
REQUIRED
generated: B3OS creates a random 32-byte secret per subscription and exposes it once to the subscribe call as subscription.secret. subscribe_result: the provider returns the secret; subscribe.secret extracts it. user: the customer supplies it when creating the subscription, as an api_key vault connection (verification-only: no pack, no hosts) bound under the routine trigger's connections.webhook_secret. The secret is stored in the vault, never in subscription state.
Enum:
generated, subscribe_result, userheader
string
hmac_sha256 only: signature header.
encoding
unknown
hmac_sha256 only. Default hex.
Enum:
hex, base64prefix
string
hmac_sha256 only: literal prefix before the signature, e.g. sha256=.
timestampHeader
string
hmac_sha256 only, and required there: header carrying the delivery's Unix timestamp; the signed payload is '<timestamp>.<body>'.
toleranceS
integer
Timestamped schemes: the largest allowed distance in seconds between the delivery's timestamp and the node clock.
subscribe
object
webhook: action called when a subscription is created (REST hooks). CEL context for with: config, subscription {id, url, secret (only when verify.secret.from is generated)}. state and secret are evaluated with result (the action output), config and subscription.
action
string
REQUIRED
Action or trigger key, kebab-case, unique within the pack.
with
unknown
REQUIRED
Any JSON value. Strings inside it (at any depth) are template strings; object keys are literal.
state
unknown
Non-secret state kept with the subscription (for example the provider's hook id), later available as subscription.state.
secret
string
Required when verify.secret.from is subscribe_result: extracts the signing secret from result. Stored in the vault.
unsubscribe
object
webhook: action called when the subscription is deleted. CEL context for with: config, subscription {id, url, state}.
action
string
REQUIRED
Action or trigger key, kebab-case, unique within the pack.
with
unknown
REQUIRED
Any JSON value. Strings inside it (at any depth) are template strings; object keys are literal.
handshake
object
webhook: answers a provider verification request (for example Slack url_verification) without emitting an event. Evaluated after signature verification. CEL context: request, config.
if
string
REQUIRED
Exactly one CEL expression wrapped as the whole string: ${{ <cel> }}. The result keeps its CEL type (bool, int, double, string, list, map, null).
response
object
REQUIRED
status
integer
REQUIRED
contentType
unknown
Enum:
application/json, text/plainbody
unknown
Any JSON value. Strings inside it (at any depth) are template strings; object keys are literal.
dedupeKey
string
webhook: string that identifies the provider event (provider event id or delivery id). CEL context: request {method, headers (lowercase map), query, body (parsed JSON or string), received_at}, config, subscription.
filter
string
webhook: bool; false acknowledges the delivery with 2xx and emits nothing. Same context as dedupeKey.
event
unknown
Event data template. webhook default ${{ request.body }} (context as dedupeKey); poll default ${{ item }} (context: item, config); schedule default ${{ result }} when action is set, else ${{ {'scheduled_at': scheduled_at} }} (context: result, config, scheduled_at).
poll
object
poll: runs a read action of this pack on an interval and emits new items. CEL context for with: config, cursor (null on the first poll), subscription. items and cursor see result, cursor, config. The first poll records a baseline and emits nothing unless initial is emit.
action
string
REQUIRED
Action or trigger key, kebab-case, unique within the pack.
with
unknown
Any JSON value. Strings inside it (at any depth) are template strings; object keys are literal.
items
string
REQUIRED
List of raw items in result.
cursor
string
Next cursor; null keeps the previous one.
intervalMs
object
REQUIRED
Poll interval. default applies when the subscription does not choose; min is the floor a subscription may request. Plans may raise the floor (GET /v1/limits).
default
integer
REQUIRED
min
integer
REQUIRED
initial
unknown
Enum:
baseline, emitdedupe
object
poll: which items are new. unique: emit items whose key was not among the last window keys seen. greatest: emit items whose key is greater than the largest key seen (keys are ints or RFC 3339 strings).
strategy
unknown
REQUIRED
Enum:
unique, greatestkey
string
REQUIRED
Per-item key. CEL context: item, config.
window
integer
schedule
unknown | unknown
schedule: emits one event per occurrence, optionally carrying the result of a read action. Occurrences missed while the node was down follow catchUp (skip: none, latest: the newest one, all: every one within 24 h).
One of:
Option 1unknown
Option 2unknown
pricing
object
Default price for every action that does not set its own. v0.1 packs are free; the node still meters actions.call (ARCHITECTURE 4.5).
model
unknown
REQUIRED
Enum:
free, per_callusd
string
compat
object
legacyIds
object
Maps an action key in this pack to the flat action id it replaces in the old B3OS catalog (research 12.3, 13). Used by the importer so old workflows resolve.
signature
object
Publisher signature written by the publish tool and repeated in the registry record. contentHash covers the whole bundle with this member removed (README, 'Pack content hash and signature'). sig is Ed25519 over the UTF-8 bytes of 'b3pack-sig-v1\n<pack>\n<version>\n<contentHash>'. Nodes verify contentHash and sig against the registry record and the publisher's registered key before loading (ARCHITECTURE 5.5).
alg
unknown
REQUIRED
Enum:
ed25519kid
string
REQUIRED
Publisher key id as registered: <namespace>#<label>.
contentHash
string
REQUIRED
sig
string
REQUIRED
base64url without padding of the 64-byte signature.
400
The request failed validation (`invalid_request`, `invalid_url`).
401
Missing, malformed, expired or revoked credentials (`unauthorized`).
403
Authenticated but not allowed (`forbidden`, `egress_denied`).
404
No such pack or version (`pack_not_found`, `pack_version_not_found`).
429
A rate, concurrency or quota limit applies (`rate_limited`, `concurrency_limited`, `quota_exceeded`).
500
Something failed inside B3OS (`internal`). Retry with backoff.
503
The node or the product is not available right now (`node_unavailable`, `product_unavailable`, `capacity_unavailable`).
curl -X GET 'https://beta-api.b3os.org/v1/actions/packs/io.b3os/github/versions/1.0.0/manifest' \ -H 'Authorization: Bearer YOUR_API_TOKEN'
const response = await fetch('https://beta-api.b3os.org/v1/actions/packs/io.b3os/github/versions/1.0.0/manifest', { method: 'GET', headers: { "Authorization": "Bearer YOUR_API_TOKEN" }});const data = await response.json();console.log(data);
import requestsheaders = { 'Authorization': 'Bearer YOUR_API_TOKEN'}response = requests.get('https://beta-api.b3os.org/v1/actions/packs/io.b3os/github/versions/1.0.0/manifest', headers=headers)print(response.json())
200
Response
{ "pack": "io.b3os/open-meteo", "version": "1.0.0", "title": "Open-Meteo", "description": "Place search and current weather from the Open-Meteo API.", "publisher": { "id": "io.b3os", "name": "B3OS" }, "license": "MIT", "engine": "^1.0", "egress": [ { "host": "geocoding-api.open-meteo.com" } ], "actions": [ { "key": "search-places", "title": "Search places", "description": "Find places by name. Returns coordinates and time zone for each match, best match first.", "inputSchema": { "type": "object", "additionalProperties": false, "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 2, "maxLength": 100 } } }, "outputSchema": { "type": "object", "additionalProperties": false, "required": [ "places" ], "properties": { "places": { "type": "array" } } }, "effects": { "class": "read" }, "impl": { "kind": "http", "request": { "method": "GET", "url": "https://geocoding-api.open-meteo.com/v1/search", "query": { "name": "${{ input.name }}", "format": "json" } }, "response": { "map": { "places": "${{ has(response.body.results) ? response.body.results : [] }}" } } } } ]}
API Playground
Try this endpoint
GET
/v1/actions/packs/{namespace}/{name}/versions/{version}/manifest