Register an Account
accounts/register is a public operation — callable anonymously. Internally
it orchestrates accounts/create, identities/create and accounts/connect
as system calls, and returns a ready-to-use session:
curl -X POST http://localhost:3000/io \
-H "Content-Type: application/json" \
-d '{
"type": "command",
"from": "x:aB3dE5fG7hJ9kL1mN3pQ5rS7anonymous",
"to": "accounts/register",
"data": { "identifier": "ada", "secret": "seller-secret-001" }
}'import { useAuthStore } from "~/stores/auth"
const auth = useAuthStore()
// wraps agent.send({ type: "command", to: "accounts/register", … })
await auth.register("ada", "seller-secret-001"){
"type": "reply",
"from": "x:mK2nP4qR6sT8uV0w",
"to": "x:aB3dE5fG7hJ9kL1m…",
"data": {
"token": "kX9…encrypted…Zw==",
"role": "SELLER"
}
}Connect (Login)
Same shape, different operation. The reply token is opaque to the client — it
is attached to every subsequent message’s from field:
curl -X POST http://localhost:3000/io \
-H "Content-Type: application/json" \
-d '{
"type": "command",
"from": "x:aB3dE5fG7hJ9kL1mN3pQ5rS7anonymous",
"to": "accounts/connect",
"data": { "identifier": "reader", "secret": "buyer-secret-001" }
}'await auth.connect("reader", "buyer-secret-001")
// store.set("auth/token", …) + agent identity applied{
"type": "reply",
"data": {
"token": "pQ4…encrypted…Yg==",
"role": "BUYER"
}
}Create a Catalog (Seller)
Requires the SELLER capability — the token in from now carries the
seller’s identity. The catalog binds itself to the fiction rule set:
curl -X POST http://localhost:3000/io \
-H "Content-Type: application/json" \
-d '{
"type": "command",
"from": "x:aB3dE5fG7hJ9kL1mN3pQ5rS7<token>",
"to": "catalogs/create",
"data": { "name": "Science Fiction Shelf", "rules": "fiction" }
}'const { createCatalog } = useCatalogs()
await createCatalog({
name: "Science Fiction Shelf",
rules: "fiction",
}){
"type": "reply",
"data": {
"success": true,
"id": "ctl_92hf30a1"
}
}Add a Book — Rejected by the Rules Engine
The fiction rule set requires an ISBN. This request omits it, so
validateItem throws before anything is written — and the typed error travels
to the client as a 400:
curl -X POST http://localhost:3000/io \
-H "Content-Type: application/json" \
-d '{
"type": "command",
"from": "x:aB3dE5fG7hJ9kL1mN3pQ5rS7<token>",
"to": "books/add",
"data": {
"catalogId": "ctl_92hf30a1",
"price": 12.99,
"meta": { "title": "Dune", "author": "Frank Herbert" }
}
}'{
"type": "invalid",
"message": "Field \"isbn\" is required",
"errors": []
}Add the ISBN and the same request succeeds:
curl -X POST http://localhost:3000/io \
-H "Content-Type: application/json" \
-d '{
"type": "command",
"from": "x:aB3dE5fG7hJ9kL1mN3pQ5rS7<token>",
"to": "books/add",
"data": {
"catalogId": "ctl_92hf30a1",
"price": 12.99,
"meta": {
"title": "Dune",
"author": "Frank Herbert",
"isbn": "978-0441172719",
"genre": "sci-fi"
}
}
}'const { addBook } = useBooks()
await addBook({
catalogId: "ctl_92hf30a1",
price: 12.99,
meta: {
title: "Dune",
author: "Frank Herbert",
isbn: "978-0441172719",
genre: "sci-fi",
},
}){
"type": "reply",
"data": {
"success": true,
"id": "bk_7f3a2c9d"
}
}List Books with Filters
A paginated read. On the client this is the useBooks composable — refs in
the query key re-run it when page or filters change:
curl -X POST http://localhost:3000/io \
-H "Content-Type: application/json" \
-d '{
"type": "command",
"from": "x:aB3dE5fG7hJ9kL1mN3pQ5rS7<token>",
"to": "books/list",
"data": {
"page": 1,
"pageSize": 10,
"filters": { "genre": "sci-fi" }
}
}'const { books, totalPages, applyFilters } = useBooks()
applyFilters({ genre: "sci-fi" })
// query re-runs; books/totalPages update reactively{
"type": "reply",
"data": {
"books": [
{
"id": "bk_7f3a2c9d",
"price": 12.99,
"meta": {
"title": "Dune",
"genre": "sci-fi"
}
}
],
"total": 17,
"totalPages": 2
}
}Liveness Ping
The one message that skips the agent entirely — the transport echoes the data back, making it a dependency-free health probe:
curl -X POST http://localhost:3000/io \
-H "Content-Type: application/json" \
-d '{
"type": "command",
"from": "x:aB3dE5fG7hJ9kL1mN3pQ5rS7anonymous",
"to": "io/ping",
"data": { "echo": "ok" }
}'{ "echo": "ok" }