Summary
The agent skill at skills/basecamp/SKILL.md advertises "Full API coverage: 155 endpoints" but does not mention Pings (Basecamp's 1-on-1 / small group direct messages, surfaced in the UI as the Pings inbox section).
Pings ARE accessible through the existing CLI — there is no missing functionality, only missing documentation. An agent reading the current SKILL.md concludes pings are not supported and falls back to browser automation or refuses the request. This is a small documentation gap with an outsized impact on agent behaviour.
What I verified
-
Pings appear in basecamp notifications with section: "pings" and a bucket.type of Circle. The app_url follows pattern /circles/<bucket_id> rather than /buckets/<id>/....
-
Ping threads are readable via basecamp api get using the standard Chat lines endpoint:
GET /buckets/<bucket_id>/chats/<chat_id>/lines.json
Returns the full conversation as an array of Chat::Lines::RichText and Chat::Lines::Upload records — same shape as Campfire lines. Each record exposes creator.name, created_at, content (HTML), and attachments[].
-
The chat IDs needed are returned in the ping notification itself. The subscription_url (/buckets/<bucket_id>/recordings/<chat_id>/subscription.json) contains both.
What I have not verified
- Posting a ping line — the BC3 API docs (
sections/campfires.md) document POST /buckets/<bucket_id>/chats/<chat_id>/lines.json for Campfire lines. Pings store on the same Chat::Transcript model, so the same POST should work with a Circle bucket. I did not test this against a live thread to avoid sending a test ping to a real person, but the API surface strongly implies it is supported.
Proposed SKILL.md additions
Three small inserts. None remove or alter existing content.
1. Add to the Quick Reference table (after the "Post to chat" row)
| List pings (cross-account) | `basecamp notifications --jq '.data.reads[] \| select(.section == "pings")'` |
| Read ping thread | `basecamp api get "/buckets/<circle_id>/chats/<chat_id>/lines.json" --agent` |
| Post to ping thread | `basecamp api post "/buckets/<circle_id>/chats/<chat_id>/lines.json" --data '{"content":"<p>message</p>"}'` |
2. Add a "Pings (Direct Messages)" subsection under Resource Reference (after the "Chat" section)
### Pings (Direct Messages)
Pings are Basecamp's 1-on-1 and small-group direct messages, surfaced in the UI as the "Pings" inbox section. They are stored as `Chat::Transcript` records inside a `Circle` bucket and accept the same line API as Campfires.
**There is no dedicated `basecamp pings` subcommand.** Use `notifications` to discover ping threads and `api` to read or post lines.
**Find your active ping threads:**
```bash
# All ping notifications (each ping channel surfaces as a notification when there's activity)
basecamp notifications --jq '.data.reads[] | select(.section == "pings") | {bucket_name, app_url, chat_id: (.subscription_url | capture("recordings/(?<id>[0-9]+)") | .id)}'
```
The `bucket.id` returned by notifications is the Circle (ping channel) ID. The chat transcript ID is embedded in `subscription_url` as `/recordings/<id>/subscription.json`.
**Read a ping thread:**
```bash
basecamp api get "/buckets/<circle_id>/chats/<chat_id>/lines.json" --agent
```
Returns all lines in the thread, oldest first paginated. Each entry has:
- `creator.name` — who sent it
- `created_at` — ISO 8601 timestamp
- `content` — rich-text HTML (strip tags for plain text)
- `attachments[]` — voice notes, files, images (use `attachments download` to fetch)
- `type` — `Chat::Lines::RichText`, `Chat::Lines::Upload`, etc.
**Post a ping line:**
```bash
basecamp api post "/buckets/<circle_id>/chats/<chat_id>/lines.json" \
--data '{"content":"<p>Hey, quick question about the listing.</p>"}'
```
Content accepts HTML. For @mentions, use the same Markdown mention syntax documented elsewhere in this skill.
**Parsing a ping URL:**
Ping URLs use the `/circles/<id>` pattern, not the standard `/buckets/<id>/...` pattern. `basecamp url parse` does not currently resolve these. Extract the Circle ID manually:
```bash
echo "https://app.basecamp.com/6049920/circles/44024535@9927050443" \
| sed -E 's|.*/circles/([0-9]+)(@([0-9]+))?.*|circle:\1 line:\3|'
# circle:44024535 line:9927050443
```
**Caveats:**
- Pings do not appear in `basecamp recordings <type>` — they are not in the standard cross-project recording index.
- The line POST has not been tested against this skill's contributor's account. Pattern matches BC3 Campfires API; verify before relying on it in critical workflows.
3. Update the description frontmatter
Add pings to the comma list in the description:
Interact with Basecamp via the Basecamp CLI. Full API coverage: projects, todos, cards, messages, files, schedule, check-ins, timeline, recordings, templates, webhooks, subscriptions, lineup, chat, pings, gauges, assignments, notifications, and accounts.
Why this matters
An agent reading the current skill encounters the explicit claim of "full API coverage" and the absence of pings in that list. It correctly concludes the API does not expose pings — when in fact the data is freely accessible through the notifications and api commands. This causes:
- Agents falling back to browser automation (slower, more brittle)
- Agents declining to read/send pings ("not supported")
- Users assuming the BC3 API doesn't cover pings when it does
The fix is documentation-only. No CLI code changes required.
Optional follow-up
A dedicated basecamp pings subcommand mirroring basecamp chat would be the cleanest UX. Suggested shape:
basecamp pings list # All ping channels (bucket_name, last activity)
basecamp pings show <circle_id> # Recent lines from one ping
basecamp pings post <circle_id> "<message>" # Post a line
basecamp pings post <circle_id> --file voice.m4a # Post an attachment
This would require CLI changes; the documentation patch above stands on its own and unlocks the workflow immediately.
Summary
The agent skill at
skills/basecamp/SKILL.mdadvertises "Full API coverage: 155 endpoints" but does not mention Pings (Basecamp's 1-on-1 / small group direct messages, surfaced in the UI as the Pings inbox section).Pings ARE accessible through the existing CLI — there is no missing functionality, only missing documentation. An agent reading the current SKILL.md concludes pings are not supported and falls back to browser automation or refuses the request. This is a small documentation gap with an outsized impact on agent behaviour.
What I verified
Pings appear in
basecamp notificationswithsection: "pings"and abucket.typeofCircle. Theapp_urlfollows pattern/circles/<bucket_id>rather than/buckets/<id>/....Ping threads are readable via
basecamp api getusing the standard Chat lines endpoint:Returns the full conversation as an array of
Chat::Lines::RichTextandChat::Lines::Uploadrecords — same shape as Campfire lines. Each record exposescreator.name,created_at,content(HTML), andattachments[].The chat IDs needed are returned in the ping notification itself. The
subscription_url(/buckets/<bucket_id>/recordings/<chat_id>/subscription.json) contains both.What I have not verified
sections/campfires.md) documentPOST /buckets/<bucket_id>/chats/<chat_id>/lines.jsonfor Campfire lines. Pings store on the sameChat::Transcriptmodel, so the same POST should work with a Circle bucket. I did not test this against a live thread to avoid sending a test ping to a real person, but the API surface strongly implies it is supported.Proposed SKILL.md additions
Three small inserts. None remove or alter existing content.
1. Add to the Quick Reference table (after the "Post to chat" row)
2. Add a "Pings (Direct Messages)" subsection under Resource Reference (after the "Chat" section)
3. Update the description frontmatter
Add
pingsto the comma list in the description:Why this matters
An agent reading the current skill encounters the explicit claim of "full API coverage" and the absence of pings in that list. It correctly concludes the API does not expose pings — when in fact the data is freely accessible through the
notificationsandapicommands. This causes:The fix is documentation-only. No CLI code changes required.
Optional follow-up
A dedicated
basecamp pingssubcommand mirroringbasecamp chatwould be the cleanest UX. Suggested shape:This would require CLI changes; the documentation patch above stands on its own and unlocks the workflow immediately.