contact-support
July 30, 2026 · View on GitHub
Work in progress — concept stage. The idea and the data model are worked out and the Twilio entry is genuinely verified, but nothing here has been driven end to end against a live support desk yet. The skills have not been exercised on a real ticket, so treat the send and follow-up paths as untested. Expect the schema to move.
A Claude Code plugin for dealing with vendors' support desks — from a registry of verified contact routes, not from what a model remembers.
Ask an agent for a company's support email and it will give you one. It will have the right shape and it will often be wrong. Support details are the worst case for recall — low-salience, changed without announcement, and wrong in a way that costs a support window rather than failing loudly.
Verifying Twilio properly turned up how bad it gets:
help@twilio.comdoes not exist. The help-centre article whose entire purpose is explaining how to contact Twilio support contains nomailto:link of any kind. Twilio publishes no general support email at all. Anysupport@orhelp@address attributed to them is somebody's guess.- Twilio's spam-reporting article prints one address and links another. The visible link text reads
spam@twilio.com; themailto:href behind it isstopspam@twilio.com. Every scraper, search index and language model reproduces the visible string — so the address nearly everyone has is the one that isn't wired up. The href is what the registry records. fraud@twilio.comis real, confirmed as a livemailto:href on Twilio's fraud-response guide and again in an independent archive snapshot.
So this plugin does not recall. It reads a registry where every claim carries the date it was last checked and whether it was confirmed directly, merely referenced by the vendor, or inferred. Then it uses that to actually contact them: draft the request with the identifiers the desk will demand, send it through whichever channel it can reach, log it, and chase it when the response window elapses.
What it does
| Skill | Question |
|---|---|
support-lookup | How do I reach these people, on this plan, for this kind of problem? |
support-account | Who am I to this vendor — account number, plan, where the credentials live? |
support-request | Write a request their desk can act on without a round trip. |
support-send | Send it, through the channel that actually works. |
support-followup | What is still open, how overdue, and how do I escalate? |
support-add-service | Research a vendor and add them to the registry. |
support-revalidate | Re-check what has gone stale, and restamp only what was checked. |
Or run the lot: /contact-support twilio our A2P campaign was rejected again
Install
/plugin marketplace add danielrosehill/Claude-Code-Plugins
/plugin install contact-support@danielrosehill
Use
/contact-support twilio messages to +44 numbers stopped delivering at 14:00
/contact-support twilio billed twice in July --draft-only
/contact-support --status
/contact-support twilio --revalidate
Or just say it: "how do I contact Twilio support", "open a ticket with Twilio about this", "has anyone replied to that ticket yet", "remember my Twilio account number", "add Cloudflare to the registry".
What a service entry holds
One JSON file per vendor. The Twilio entry —
data/services/twilio.json — is the reference for what a good one looks
like:
- Channels, ranked, each with what it is good for, what it will bounce, which support plans can use it, whether an agent can actually drive it, and the response time to expect.
- Identifiers the desk needs, with where to read each one off in the vendor's UI — and which ones are secrets, marked so they can be refused.
- Priority levels in the vendor's own vocabulary, because their words route the ticket.
- Escalation ladder, with a real trigger on each rung, including the SLA credit claim and its deadline.
- Before you contact — the checks that resolve the issue or pre-empt the desk's first question.
known_dead— the routes that look right and are not.- Gotchas learned the hard way.
known_dead is the point
The Twilio pass turned up nine dead routes, and the interesting ones are invisible to any link checker:
spam@twilio.com— printed by Twilio, not wired up. Themailto:behind that link text isstopspam@twilio.com. A link checker never looks at link text; a scraper never looks at the href.discord.gg/twilioreturns 301 to a Discord invite that the invites API resolves asUnknown Invite. A live redirect fronting a dead resource.help.twilio.comreturns 200 with nothing but a<title>— a client-rendered app that gives a fetcher no content at all, including on its/api/v2/help_center/path.support.twilio.com/hc/en-usreturns 403 to non-browser clients while working perfectly in a browser, so it is neither dead nor checkable the easy way.
A status code is not a verdict. That is why scripts/check_registry.py validates and ages entries but
deliberately does not test reachability, and why evidence is mandatory on any channel claiming
confirmed.
How the unreadable pages got read
help.twilio.com gives a fetcher nothing, which is why most of what is written about Twilio support
comes from search snippets rather than the source. The way through: support.twilio.com — the
pre-2024 Zendesk it replaced — was server-rendered, and the Wayback Machine has it. Article IDs
survived the migration, so a snapshot of the old host yields the body of the current article, mailto:
hrefs intact. That is how the stopspam@ mismatch surfaced, and how the plan/channel matrix below
stopped being a guess.
What that matrix actually says
| Plan | Help Center Assistant | Direct ticket link | Live chat | Phone |
|---|---|---|---|---|
| Developer (free) | ✅ | ❌ | ❌ | ❌ |
| Production | ✅ | ✅ | ✅ | ❌ |
| Business | ✅ | ✅ | ✅ | ✅ |
| Personalized | ✅ | ✅ | ✅ | ✅ |
On the free plan the AI assistant is the only route to a ticket — there is no direct Submit-a-Ticket link, so hunting for one and failing is not a bug in the account. Chat starts at Production, phone at Business; neither is simply "paid plans". And eleven products are ticket-only whatever you pay, Studio and Conversations among them.
Your data stays yours
~/.claude-plugins/contact-support/
├── accounts.json who you are to each vendor
├── services/<slug>.json your own entries, and overrides on the shipped ones
└── tickets/<slug>/<date>-*.md one file per interaction, with the response due date
Outside the plugin directory, because /plugin update replaces that. Your overrides win over the
shipped registry; accumulated lists like known_dead concatenate rather than replace; and the older
of the two verification dates governs a merged entry, so a fresh override cannot make stale channels
look trustworthy.
Credentials are pointers, never values. accounts.json stores account numbers — support desks ask
for those and they get sent. Where a password or token lives is stored as a reference
(op://Private/Twilio/credential, an env var name, a vault item title) so the agent can tell you where
to look without the secret passing through a transcript, a draft, or a saved file. Nothing in that
block is ever sent anywhere.
Start from examples/accounts.example.json.
Guardrails that do real work
- Drafting and sending are separate.
support-requeststops at a draft.support-sendquotes the destination back and waits for a yes. One approval, one send — it does not roll forward to a retry or another channel. - The reachable channel is not automatically the right one. A login-gated ticket form is hard and
correct; a public forum is easy and wrong.
not_forandagent_reachableexist so that "I could reach this one" never becomes the reason a problem gets published with an account number attached. - No identifiers on public channels. Ever.
- No credentials in outbound messages. If a support flow appears to require one, that is a phishing signal, not a field to fill.
- No duplicate tickets. A second ticket splits the history and usually resets queue position.
- No probe emails when revalidating. Mailing a support address to see if it exists creates a ticket someone has to close.
Ships with Twilio. Extend it.
One vendor verified properly beats twelve verified by assumption — a registry of guesses would defeat the whole point. Twilio is here because it is what the author needed and because it exercises every field in the schema: a separate desk for Segment, a product with its own abuse address, tiered SLAs with a time-barred remedy, a retired forum, and six dead routes.
Add your own with support-add-service, which does the research, reaches each target, grades every
claim, and records the dead ends. Entries land in ~/.claude-plugins/contact-support/services/ and stay yours. Fork
this repo if you would rather ship a registry for your own stack, or open a PR if an entry is worth
everyone having.
Verification history for the shipped entries: docs/verification-log.md.
Why it is built this way: docs/design-notes.md.
Checking the registry
./scripts/check_registry.py # schema-validate everything, report what is due
./scripts/check_registry.py --json
Runs via uv with an inline dependency header — no environment to set up.
Licence
MIT.