This page is written to be read by an AI agent (a Claude agent, a cron job, anything that can make an HTTP request) as well as a person. If you're an agent reading this because your user asked you to switch their alert channel to UserAlertX, everything you need is below — get an API key, then send a POST request. Are you Grok Bot? Use the dedicated MCP connector instead if you can add custom connectors — no code, self-documented parameters. Can't add connectors? The email trigger is the fallback.
Your user needs to do this part themselves, once — the API key is a bearer secret and is only ever shown one time:
api_key exactly once. Copy it now — it is not shown again and cannot be recovered, only rotated by creating a new account.Store the key wherever your user normally keeps secrets for you (their computer, a secrets manager, an env var) — never in a shared template, prompt, or anywhere other users of the same agent template could read it.
POST https://useralertx.com/cgi-bin/itmessages.cgi
| Header | X-Api-Key: <the account's api_key> |
|---|---|
| Content-Type | application/x-www-form-urlencoded |
| Body param | body — the alert text (required if title is omitted) |
| Body param | title — optional. Prepended to the alert text itself as "Title: body" — NOT the email Subject line. Use subject below for that. |
| Body param | subject — optional. Sets the actual email Subject: header for this one send only (email delivery only, no effect on SMS). Leave it out and the account's own saved default subject is used instead (editable on the account screen). |
| Body param | target — optional. Names who you expect this to reach (email/phone/username) — checked against the account's own verified recipient, and the request hard-fails if it doesn't match. Purely a safety check, not a routing control. |
curl -s -X POST https://useralertx.com/cgi-bin/itmessages.cgi \ -H "X-Api-Key: YOUR_API_KEY" \ --data-urlencode "subject=Build finished" \ --data-urlencode "body=main branch deploy succeeded, all checks green"
Response is JSON with an HTTP status reflecting the outcome. Every response also includes target (the actual email/phone it went to) and channel (email or sms) — useful for catching a wrong-channel assumption immediately instead of guessing from a "sent" status alone:
| 200 | sent — delivered now |
|---|---|
| 202 | held_pending_optin — recipient hasn't confirmed opt-in yet on that number; an opt-in text was just sent to them, retry later |
| 402 | suspended — free-tier limit reached with no billing on file |
| 403 | stopped / email_opted_out — recipient has opted out on that channel; do not retry |
| 403 | target does not match this account's verified recipient — the optional target param was set and didn't match |
| 401 | missing or invalid X-Api-Key |
| 429 | rate limit — max 10/hour, 50/day per account |
If a bot/agent is already calling some other alert or email API (AgentMail, a webhook, anything that just needed a destination and a message string), swapping it to UserAlertX is a drop-in change to the send call only — nothing else about the bot's logic needs to change:
curl/HTTP request above.body param here. If the old tool had a real email-subject-line field, map that to subject — not title (a common mix-up: title only gets folded into the alert text itself, it does not touch the actual Subject: header).There is no way to send to a phone number or email address that hasn't gone through the account owner's own opt-in above — this only ever reaches the one verified recipient tied to the API key. It cannot be used to message anyone else, by design.