Edited 2026-08-04. The original report generalized from one posting and asked for a topic_id on every posting. That ask can't be satisfied for the affected postings — they're bundles, which name a contact rather than a thread. Rewritten below against a 500-posting sample; the real gap is bundle expansion.
Problem
hey box --json lists two kinds of posting, and only one of them can be handed to hey threads.
kind |
count |
app_url |
app_bundle_url |
resolvable |
topic — one message |
262 |
/topics/<n> (100%) |
absent |
yes, via app_url |
bundle — single entry |
70 |
/contacts/<n> |
/topics/<n> |
yes, via app_bundle_url |
bundle — multi message |
168 |
/contacts/<n> |
/postings/<n>/bundles/unseen or /contacts/<n> |
no |
Counts are from one Imbox, hey box imbox --json --limit 500, version a3cf885.
A bundle is HEY's per-contact digest — several messages from one sender collapsed into one row. Its app_url is contact-shaped because it names a contact, not a thread. When a bundle happens to wrap a single message it still points at that one topic via app_bundle_url, so it is readable. When it wraps several, there is no single topic to name and the messages inside become unreachable from the CLI.
Separately: no posting in the sample carries a topic_id field in any casing — the embedded skill's claim that one is present for every posting is not met by any live response. The topic ID is only ever available from a navigation URL. (Addressed in #157.)
Expected
A read-only way to list the topics inside a bundle posting — the equivalent of the web app's /postings/<id>/bundles/unseen route. For example hey box --bundle <posting-id> --json, or accepting a bundle posting ID in an existing listing command.
Asking for a topic_id on every posting (as this issue originally did) is the wrong shape: a multi-message bundle has no single topic ID to return.
Actual
There is no route to a bundle's contents. Against the ULink bundle (324431450, app_url and app_bundle_url both /contacts/21365740), every plausible call returns not-found:
$ hey threads 324431450 --json
{"ok": false, "error": "Resource not found: https://app.hey.com/topics/324431450/entries", "code": "not_found"}
$ hey threads 21365740 --json # the contact ID
{"ok": false, "error": "Resource not found: https://app.hey.com/topics/21365740/entries", "code": "not_found"}
$ hey box 324431450 --json
{"ok": false, "error": "resource not found", "code": "not_found"}
$ hey box 21365740 --json
{"ok": false, "error": "resource not found", "code": "not_found"}
hey box accepts only a box name or box ID, so there is no command that takes a posting ID at all. The generated SDK Posting type has no topic-ID field.
Impact
Read-only automation over the Imbox can list a bundled sender's mail but never read it. In practice this hits exactly the senders worth automating — schools, teams, and other institutions that send frequently enough to get bundled. A newsletter I extract dates from is unreachable for this reason, while ad-hoc one-off senders read fine.
The failure is also silent in a damaging way: an agent that substitutes the posting ID gets a 404 from /topics/<posting-id>/entries and can report "no content" rather than "unreadable".
Reproduction
hey box imbox --json --limit 500
- Find a posting with
"kind": "bundle" whose app_bundle_url is not a /topics/<id> route (168 of 500 above).
- Note there is no
topic_id and no topic-shaped URL anywhere on the posting.
- Try
hey threads <posting-id>, hey threads <contact-id>, hey box <posting-id>, hey box <contact-id> — all return not-found.
Happy to provide a sanitized response shape or test a proposed fix.
Problem
hey box --jsonlists two kinds of posting, and only one of them can be handed tohey threads.kindapp_urlapp_bundle_urltopic— one message/topics/<n>(100%)app_urlbundle— single entry/contacts/<n>/topics/<n>app_bundle_urlbundle— multi message/contacts/<n>/postings/<n>/bundles/unseenor/contacts/<n>Counts are from one Imbox,
hey box imbox --json --limit 500, versiona3cf885.A
bundleis HEY's per-contact digest — several messages from one sender collapsed into one row. Itsapp_urlis contact-shaped because it names a contact, not a thread. When a bundle happens to wrap a single message it still points at that one topic viaapp_bundle_url, so it is readable. When it wraps several, there is no single topic to name and the messages inside become unreachable from the CLI.Separately: no posting in the sample carries a
topic_idfield in any casing — the embedded skill's claim that one is present for every posting is not met by any live response. The topic ID is only ever available from a navigation URL. (Addressed in #157.)Expected
A read-only way to list the topics inside a bundle posting — the equivalent of the web app's
/postings/<id>/bundles/unseenroute. For examplehey box --bundle <posting-id> --json, or accepting a bundle posting ID in an existing listing command.Asking for a
topic_idon every posting (as this issue originally did) is the wrong shape: a multi-message bundle has no single topic ID to return.Actual
There is no route to a bundle's contents. Against the ULink bundle (
324431450,app_urlandapp_bundle_urlboth/contacts/21365740), every plausible call returns not-found:hey boxaccepts only a box name or box ID, so there is no command that takes a posting ID at all. The generated SDKPostingtype has no topic-ID field.Impact
Read-only automation over the Imbox can list a bundled sender's mail but never read it. In practice this hits exactly the senders worth automating — schools, teams, and other institutions that send frequently enough to get bundled. A newsletter I extract dates from is unreachable for this reason, while ad-hoc one-off senders read fine.
The failure is also silent in a damaging way: an agent that substitutes the posting ID gets a 404 from
/topics/<posting-id>/entriesand can report "no content" rather than "unreadable".Reproduction
hey box imbox --json --limit 500"kind": "bundle"whoseapp_bundle_urlis not a/topics/<id>route (168 of 500 above).topic_idand no topic-shaped URL anywhere on the posting.hey threads <posting-id>,hey threads <contact-id>,hey box <posting-id>,hey box <contact-id>— all return not-found.Happy to provide a sanitized response shape or test a proposed fix.