> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# IDs and object shapes

How B3OS IDs are built, which prefix belongs to which object, and the fields every object, list and credential shares.

Every object B3OS creates has an ID made of a prefix, an underscore and a ULID in lowercase Crockford base32: `sbx_01m5t68q1b590rj801nbzsqzkk`. The prefix tells you the object type at a glance, and IDs created later sort later.

## Prefixes

| Prefix | Object | Product |
|---|---|---|
| `brs_` | `browser_session` | vision |
| `prof_` | `profile` | vision |
| `crawl_` | `crawl` | vision |
| `batch_` | `batch_scrape` | vision |
| `shot_` | `screenshot` | render |
| `vid_` | `video` | render |
| `art_` | `artifact` | render |
| `sbx_` | `sandbox` | sandboxes |
| `snap_` | `snapshot` | sandboxes |
| `tpl_` | `template` | sandboxes |
| `rtn_` | `routine` | routines |
| `ver_` | `routine_version` | routines |
| `run_` | `routine_run` | routines |
| `hk_` | `hook` (secret) | routines |
| `conn_` | `connection` | vault |
| `tsub_` | `trigger_subscription` | actions |
| `clink_` | `connect_link` | vault |
| `org_` | `organization` | platform |
| `prj_` | `project` | platform |
| `key_` | `api_key` | platform |
| `req_` | `request` | platform |
| `use_` | `usage_record` | platform |
| `job_` | `job` | platform |
| `tkt_` | `stream_ticket` (secret) | platform |
| `evt_` | `event` | platform |
| `usr_` | `user` | platform |

IDs marked secret (`hk_` hooks and `tkt_` stream tickets) carry no timestamp and cannot be guessed, because holding one grants something: a hook ID is the URL a provider posts to, and a ticket opens a stream. Treat them like passwords.

Packs and actions have names instead of IDs: a pack is `<namespace>/<name>` such as `io.b3os/github`, and an action is `<namespace>/<name>/<action>@<version>` such as `io.b3os/github/create-issue@1.2.0`. The namespace is a reverse-DNS name with at least one dot.

## Host-safe form

DNS labels and some URL paths cannot hold an underscore, so B3OS writes the same ID with a hyphen where it needs to: `sbx-01m5t68q1b590rj801nbzsqzkk`. A sandbox's `host_id` field and the paths of port previews and artifact URLs on `usercontent.b3os.org` use this form. API paths always take the underscore form.

## Credentials

| Prefix | Kind | Format |
|---|---|---|
| `b3os_sk_` | api key | API key. 32 lowercase RFC 4648 base32 characters (160 bits), then `_` and the CRC-32 (IEEE) of everything before that underscore as 8 lowercase hex digits. Registered for secret scanning. |
| `b3os_pat_` | cli token | CLI token from the device login, same layout as API keys. |
| `b3os_nt_` | node token | Edge-to-node token, `b3os_nt_<b64url(payload)>.<b64url(ed25519 signature)>`, 60-second TTL. Never issued to customers. |
| `whsec_` | webhook secret | Webhook signing secret for one endpoint URL. |
| `pt1.` | port token | Sandbox port preview token, `pt1.<node>.<exp>.<b64url(ed25519 signature)>`, carried in the path of `usercontent.b3os.org/sbx/<sandbox host id>/<port>/<token>/` URLs. Signed by the node key over `"b3os-port-v1\n" + node + "\n" + sandbox_id + "\n" + port + "\n" + exp` (openapi/sandboxes.yaml, `sandboxesProxyPortGet`). Anyone holding it reaches the port until `exp`. |

The checksum lets a client or a secret scanner reject a mistyped or made-up key without a network call.

## Fields every object shares

| Field | Meaning |
|---|---|
| `id` | The prefixed ID. |
| `object` | The type name, such as `sandbox`, `browser_session` or `routine_run`. |
| `created_at` | RFC 3339 timestamp in UTC. |
| `metadata` | Up to 16 string pairs you attach for your own use. Keys are 1 to 40 characters of `A-Z a-z 0-9 _ . : -`; values are at most 500 characters. B3OS never reads them. |
| `status` | Present on objects with a lifecycle, such as sandboxes, sessions and jobs. |

Deleting returns `{"id": "...", "object": "...", "deleted": true}`, except for objects whose final state matters: deleting a sandbox or closing a browser session returns the final object with its usage, and revoking a key returns the revoked key, which stays listed for audit.

## Lists

Every list takes `?limit=` (1 to 100) and `?cursor=`, and returns:

```json
{ "object": "list", "data": [ ... ], "next_cursor": "..." }
```

Pass `next_cursor` back as `cursor` for the next page. It is `null` on the last page. Cursors are opaque; do not build them yourself.