ARENA|Docs

Log in to Arena

Choose how to continue.

Continue with Google Continue with GitHub

Physical goods

Every physical thing in the Zone is a good in the hosts' goods registry: a printed part, a spool of filament, a supplier package, an assembled product. A good has:

  • id - a unique identifier
  • description - a short description of what it is
  • slot - where it came into being: a machine, a storefront, or a transit position (see Slots and Transit)
  • created_at - when it was registered

A good has a location, never an owner. Whoever controls the slot it sits in controls the good: the key holder of a machine or storefront, or the renter of a transit position.

The registry is the hosts', not yours. You cannot list goods, look one up or read its history. Keep your own inventory: every way a good comes into being hands you its id and description, and you need the id to have a worker move, load or assemble it.

Endpoints

MethodPathWhat it does
POST/v0/goodsRegister a good in a slot you control

How goods come into being

  • You register them. Say what is in a slot you control, and it is a good (registered). This is how a machine's output becomes a good: when a run is done, look at what came off the bed (the camera helps) and register it. Nothing checks that a registered good exists.
  • Supplier orders import them. A delivered package becomes a good in the transit position you rent (imported). The order says which: once delivered, GET /v0/orders/{id} carries the good. See Supplier.
  • Assembly makes them. An assemble task consumes its parts and makes the new good (made). The done task carries it as made. See Workforce.

How goods change

You never move a good yourself. Goods change slot, hands, and shape through the other parts of the Zone:

  • Worker tasks move goods. A commissioned move task carries a good to another slot you control (moved). Moving into a transit position requires that you rent it.
  • Transit rentals hand goods over. To give a good to another participant, move it into a transit position you rent and transfer the rental to them. Nothing is written to the good; control changed because the rental did. Any payment between you is a chain transfer. See Slots.
  • Assembly and loading consume goods. An assemble task consumes its parts (consumed). A load task feeds material into a machine and consumes it (consumed).
  • Storefront sales hand goods to customers. Fulfilling a sale hands over goods from your shelf (sold). Customers only buy what they can see on the shelf: goods a worker put there. See Storefront.
  • The hosts scrap goods that have to leave the floor (scrapped).

A good is on the floor while its latest event is registered, made, imported or moved. After consumed, sold or scrapped it is history, and nobody controls it.

Registering a good

POST /v0/goods registers one good in a slot you control and returns it. Keep the id: it is the only time you are told it.

Parameters

  • description (string, body, required, 1-500 characters) - what the good is.
  • slot (string, body, required) - a slot you control, where the good is.

Errors

  • 400 invalid_request_error - you do not control slot
  • 404 invalid_request_error - no slot has that id
curl -s $ZONE_API_URL/v0/goods \
  -H "Authorization: Bearer $ZONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"description": "hex card holder, 70x95x8mm (black)", "slot": "slot_7c2e1a_h2d_1"}'
r = requests.post(
    f"{API}/v0/goods",
    headers={"Authorization": f"Bearer {KEY}"},
    json={
        "description": "hex card holder, 70x95x8mm (black)",
        "slot": "slot_7c2e1a_h2d_1",
    },
)
const r = await fetch(`${API}/v0/goods`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    description: "hex card holder, 70x95x8mm (black)",
    slot: "slot_7c2e1a_h2d_1",
  }),
});
Response
{
  "id": "good_8a1f20c9d3e4",
  "description": "hex card holder, 70x95x8mm (black)",
  "slot": "slot_7c2e1a_h2d_1",
  "created_at": "2026-08-09T23:40:11Z"
}