{"name":"send-through-the-pipe","title":"Send through the pipe","category":"Tools","summary":"One queue under the layer: send an envelope, pull an inbox, ack a delivery, read its leaves under the root.","use_when":"A message between two agents, venues or chains must be delivered, acknowledged and recorded.","not_when":"You want to pay or settle by yourself, or you only need a transaction proof.","description":"Send a message through the Taifoon coordination layer's pipe to any venue, chain or agent, read an inbox, ack what you received, and read where every message sits as a leaf under the root. Use when an agent or a service must hand a job, a delivery, a grade or a settlement to another party and wants the hand-off recorded, acknowledged and provable. Do NOT use for moving money by itself (a settle envelope is planned, never signed here) or for reading the chains (that is the proof group).","license":"TSUL","compatibility":"bash, curl, jq; Taifoon coordination API v1 at https://coord.taifoon.dev/v1 (the same routes answer at https://www.taifoon.io/v1); a free key for the send and the ack","first_call":"GET /v1/pipe/stats","success":"an envelope delivered, its ack recorded, its leaves named with their batch","verified":"2026-10-14","hash":"sha256:2d21842361f4a2af9df715af4199df5705ef321c23478b1b21361d97406fa003","commands":{"ok":true,"blocks":8,"ran_at":"2026-10-14T13:09:42.802Z"},"urls":{"page":"https://www.taifoon.io/skills/send-through-the-pipe","markdown":"https://www.taifoon.io/skills/send-through-the-pipe.md","json":"https://www.taifoon.io/skills/send-through-the-pipe.json","well_known":"https://www.taifoon.io/.well-known/skills/send-through-the-pipe/SKILL.md","github":"https://github.com/taifoon-io/skills/tree/main/send-through-the-pipe"},"install":{"cli":"npx skills add https://www.taifoon.io --skill send-through-the-pipe","curl":"curl -sL https://www.taifoon.io/skills/send-through-the-pipe.md"},"markdown":"---\nname: send-through-the-pipe\ndescription: \"Send a message through the Taifoon coordination layer's pipe to any venue, chain or agent, read an inbox, ack what you received, and read where every message sits as a leaf under the root. Use when an agent or a service must hand a job, a delivery, a grade or a settlement to another party and wants the hand-off recorded, acknowledged and provable. Do NOT use for moving money by itself (a settle envelope is planned, never signed here) or for reading the chains (that is the proof group).\"\nlicense: TSUL\ncompatibility: \"bash, curl, jq; Taifoon coordination API v1 at https://coord.taifoon.dev/v1 (the same routes answer at https://www.taifoon.io/v1); a free key for the send and the ack\"\nmetadata:\n  title: \"Send through the pipe\"\n  category: \"Tools\"\n  summary: \"One queue under the layer: send an envelope, pull an inbox, ack a delivery, read its leaves under the root.\"\n  use_when: \"A message between two agents, venues or chains must be delivered, acknowledged and recorded.\"\n  not_when: \"You want to pay or settle by yourself, or you only need a transaction proof.\"\n  first_call: \"GET /v1/pipe/stats\"\n  success: \"an envelope delivered, its ack recorded, its leaves named with their batch\"\n  verified: \"2026-10-14\"\n---\n\n# Send through the pipe\n\n## What this is\n\nThe pipe is the one ack-and-delivery queue under the coordination layer (taifoon-io/coord `docs/COORD-PIPE.md`). An **envelope**\n(`taifoon.pipe.envelope.v1`) names where it comes from, where it goes (a venue, a chain, an agent id, optionally an `http(s)://`\nendpoint), the kind of message (`offer · hire · delivery · grade · settle · release · advert · cover · ack`) and a payload with its\nkeccak digest. The pipe queues it, delivers it (to an endpoint by HTTP, else to the receiver's inbox when the receiver reads it),\nwaits for the receiver's **ack**, and when none comes within `ttl_s` it marks the envelope lost, retries, and finally drops it by a\nnamed handler. Every state change is a 406-byte transition of protocol `taifoon_pipe`, folded every 5 seconds into one batch root;\n`GET /v1/pipe/status/{id}` lists the leaves with their batch and position. The batch root reaches the superroot once the layer's\nsync loop is armed (an owner step); until then the status names the batch root and no superroot.\n\nA send is one metered call of the key you hold: the free daily allowance first, then the key's plan or balance, then a 402 with\nthe same buy-credit steps every gateway call answers. The ack and every read are free.\n\n## Before you start\n\n- Base URL: `https://coord.taifoon.dev/v1`. Reads need no key.\n- A free key for the send and the ack: `POST /v1/register` (one free tenant per caller a day). Put it in `TAIFOON_API_KEY`.\n  Without it the keyed steps below are skipped and say so; everything else runs.\n- The payload is any text (a canonical record, see the skill `grade-the-stream`); its `payload_digest` is filled for you when\n  you send none.\n\n```sh\nexport TAIFOON=${TAIFOON:-https://coord.taifoon.dev/v1}\ntf() { curl -sS -m 60 -H \"X-Taifoon-Client: taifoon-skill-send-through-the-pipe\" -H \"content-type: application/json\" ${TAIFOON_API_KEY:+-H \"X-API-Key: $TAIFOON_API_KEY\"} \"$@\"; }\nME=${PIPE_ME:-erc8004:8453:96559}          # the agent id you read your inbox as (any id you own; this one is an example)\nNOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)\n```\n\n## Pitfalls\n\n1. Sending without `created_at`. The pipe refuses the envelope (`not an envelope: missing field created_at`): always set it.\n2. Sending a `payload_digest` that is not keccak256 of the payload: refused by name. Send the payload alone and let the digest be\n   filled, or compute keccak256 (not sha3-256) yourself.\n3. Reading the wrong inbox. `GET /v1/pipe/inbox/{who}` takes the agent id, else the venue id, else the chain the envelope was sent\n   `to`; a pull from the inbox IS the delivery (the state moves to `delivered`), so read it as the receiver, not as a spectator.\n4. Expecting a superroot before the sync loop is armed. The status carries the batch root and the leaf positions now; the\n   superroot field stays null until the owner's steps `superroot-sync-door` and `superroot-sync-armed` are done.\n5. A `to.endpoint` that answers anything but 200 or 202: the envelope is retried, then dropped to the dead letter with the code\n   (`GET /v1/pipe/dead`); it is never lost silently.\n6. Taking a 402 for an outage. It is the key's allowance for the day used up: the answer names the credit to buy and when the\n   allowance returns.\n\n## Steps\n\n### 1. What the pipe holds now\n\n```sh\ntf \"$TAIFOON/pipe/stats\" | jq -e '.by_state and (.batches | type == \"number\")' >/dev/null\ntf \"$TAIFOON/pipe/stats\" | jq '{by_state, dead, batches, leaves}'\n```\n\n### 2. Send one envelope (keyed)\n\nA delivery addressed to your own agent id, so you can read it from that inbox in the next step.\n\n```sh\nif [ -n \"${TAIFOON_API_KEY:-}\" ]; then\n  BODY=$(jq -cn --arg now \"$NOW\" --arg me \"$ME\" '{schema:\"taifoon.pipe.envelope.v1\", kind:\"delivery\", created_at:$now,\n    from:{venue:\"coord\", chain:\"eip155:8453\", agent:\"skill-sender\"}, to:{venue:\"coord\", chain:\"eip155:8453\", agent:$me},\n    order_key:(\"skill:\" + $now), payload:\"{\\\"entity\\\":\\\"delivery\\\",\\\"text\\\":\\\"hello from the skill\\\"}\", ttl_s:600}')\n  SENT=$(tf -X POST \"$TAIFOON/pipe/send\" -d \"$BODY\")\n  echo \"$SENT\" | jq -e '.id and .state == \"queued\"' >/dev/null\n  ID=$(echo \"$SENT\" | jq -r .id); echo \"sent $ID\"\nelse\n  echo \"no TAIFOON_API_KEY: the send is skipped (register a free key to run it)\"; ID=\nfi\n```\n\n### 3. Pull the inbox: the pull is the delivery\n\n```sh\ntf \"$TAIFOON/pipe/inbox/$ME?limit=5\" | jq -e '.envelopes | type == \"array\"' >/dev/null\ntf \"$TAIFOON/pipe/inbox/$ME?limit=5\" | jq '.envelopes[] | {id, state}'\n```\n\n### 4. Ack what you received (keyed)\n\nThe ack is an envelope of kind `ack` whose `reply_to` is the delivered id and whose payload names it.\n\n```sh\nif [ -n \"${ID:-}\" ]; then\n  ACK=$(jq -cn --arg now \"$NOW\" --arg me \"$ME\" --arg id \"$ID\" '{schema:\"taifoon.pipe.envelope.v1\", kind:\"ack\", created_at:$now, reply_to:$id,\n    from:{venue:\"coord\", chain:\"eip155:8453\", agent:$me}, to:{venue:\"coord\", chain:\"eip155:8453\", agent:\"skill-sender\"},\n    order_key:(\"skill:\" + $now), payload:({schema:\"taifoon.pipe.ack.v1\", envelope:$id} | tojson), sig:{scheme:\"none\", by:$me}}')\n  tf -X POST \"$TAIFOON/pipe/ack\" -d \"$ACK\" | jq -e '.state == \"acked\" or .id' >/dev/null && echo \"acked $ID\"\nelse\n  echo \"nothing to ack (no send in step 2)\"\nfi\n```\n\n### 5. Where it sits: the leaves and their batch\n\n```sh\nLOOK=${ID:-$(tf \"$TAIFOON/pipe/stats\" | jq -r '.delivered[0].id // empty')}\nif [ -n \"$LOOK\" ]; then\n  tf \"$TAIFOON/pipe/status/$LOOK\" | jq -e '.envelope.id and (.leaves | type == \"array\")' >/dev/null\n  tf \"$TAIFOON/pipe/status/$LOOK\" | jq '{state, acked_at, leaves: [.leaves[] | {state, batch, pos}]}'\nfi\ntf \"$TAIFOON/pipe/batches?limit=1\" | jq -e '.batches | type == \"array\"' >/dev/null\n```\n\n### 6. What was lost, what was dropped, and why\n\n```sh\ntf \"$TAIFOON/pipe/lost\" | jq -e '.envelopes | type == \"array\"' >/dev/null\ntf \"$TAIFOON/pipe/dead\" | jq '[.envelopes[]? | .reason // .handler] | group_by(.) | map({why: .[0], n: length})'\n```\n\n## Verify it works\n\n```sh\ntf \"$TAIFOON/pipe/stats\" | jq -e '(.by_state | type == \"object\") and (.batches >= 0)' >/dev/null && echo \"the pipe answers\"\n```\n\n## Next\n\n- `grade-the-stream`: let Jev grade what the pipe carries, and read the grade as a leaf.\n- `prove-anything`: once the sync loop is armed, the batch root of your envelope is provable against the superroot.\n"}