contact-support

July 30, 2026 · View on GitHub

Status: work in progress Stage: concept Services verified: 1 Licence: MIT

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.com does not exist. The help-centre article whose entire purpose is explaining how to contact Twilio support contains no mailto: link of any kind. Twilio publishes no general support email at all. Any support@ or help@ 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; the mailto: href behind it is stopspam@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.com is real, confirmed as a live mailto: 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

SkillQuestion
support-lookupHow do I reach these people, on this plan, for this kind of problem?
support-accountWho am I to this vendor — account number, plan, where the credentials live?
support-requestWrite a request their desk can act on without a round trip.
support-sendSend it, through the channel that actually works.
support-followupWhat is still open, how overdue, and how do I escalate?
support-add-serviceResearch a vendor and add them to the registry.
support-revalidateRe-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. The mailto: behind that link text is stopspam@twilio.com. A link checker never looks at link text; a scraper never looks at the href.
  • discord.gg/twilio returns 301 to a Discord invite that the invites API resolves as Unknown Invite. A live redirect fronting a dead resource.
  • help.twilio.com returns 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-us returns 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

PlanHelp Center AssistantDirect ticket linkLive chatPhone
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-request stops at a draft. support-send quotes 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_for and agent_reachable exist 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.