Test mode
Test every failure before a customer finds it.
The same API with a test key. Your agent’s whole email pipeline runs, nothing leaves Pidgeon, nothing counts against your plan, and you can cause a bounce or a lost answer on purpose. On every plan, including Free.
curl https://pidgeon.ai/api/v1/messages \
-H "Authorization: Bearer pgn_test_…" \
-H "Content-Type: application/json" \
-d '{ "from": "support@yourapp.pidgeon.email",
"to": "customer@example.com",
"text": "On its way." }'
# 202, and nothing left Pidgeon
{
"data": {
"id": "…",
"thread_id": "…",
"rejected": [],
"test": true
}
}What runs
Production, minus the consequences.
A test key exercises the code paths a live key does. Only where the mail goes, and what it costs, changes.
- Everything runs
Validation, the send checks, threading, events and signed webhooks, receipts, Idempotency-Key, and the Firewall on mail that arrives. It is the same API, with a key that starts pgn_test_.
- Nothing leaves, nothing counts
No mail is handed to a provider and nothing counts against your plan. Rate limits still apply, in a bucket of their own, so a test suite cannot use up what production needs.
- Addresses that clean up
A test key can make test addresses of its own, up to 100 at once, outside your plan, and each is deleted a day after it was made. A fresh address for every CI run.
Failures on demand
The branches a working API never takes.
Refusals, bounces, rate limits and lost answers are where the bugs live. With a test key you can cause each one.
rejected@…A refused recipientComes back in the send’s rejected, with a reason, while everyone else on the send still gets it.
bounce@…A bounce, a few seconds laterAccepted, then a hard bounce: the delivery state turns to bounced and message.bounced reaches your webhooks.
Pidgeon-Test-Fail: 429A rate limit, or 503The error with Retry-After, and nothing done, on any request that takes an Idempotency-Key.
Pidgeon-Test-Fail: dropA lost answer, or a slow oneThe work is done and the answer is lost, or with delay=20s it comes late. Retry with the same Idempotency-Key and you get the first answer back.
Play the other side
Mail that arrives when you say.
Nobody outside answers a test send, so you send the reply yourself, through the real inbound path.
The walkthrough, with every trigger, is in the blog post and the test mode guide.
API=https://pidgeon.ai/api/v1
curl $API/test/inbound \
-H "Authorization: Bearer $PIDGEON_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "support@yourapp.pidgeon.email",
"from": "customer@example.com",
"subject": "Re: Your order",
"text": "It never arrived.",
"in_reply_to": "message-id"
}'Questions
Asked before pointing CI at it.
Is there a sandbox environment or a separate URL?
No. Test mode is the same API at the same address, with a test key. Your SDK, CLI or MCP client works unchanged; only the key is different.
Where does mail from a test key go?
Mail to your own account’s addresses is delivered there, marked test, so two of your agents can talk to each other in CI. Mail to anybody else is accepted, stored as sent, and goes nowhere.
Can a test address receive real email?
No. A test address takes test sends from your account and simulated inbound mail, and refuses mail from outside as though it did not exist.
How do I test what my agent does when a reply arrives?
POST /v1/test/inbound delivers a message to one of the test key’s addresses through the real inbound path: sender rules, the spam filter, the Firewall, threading and your webhooks. Pass in_reply_to to make it a reply in a thread.
Which failures can I cause?
A refused recipient (rejected@), a hard bounce (bounce@), and with the Pidgeon-Test-Fail header a 429, a 503, a delayed answer or a dropped one. There is no complaint trigger.
Is test mode on the free plan?
Yes, on every plan, including Free. Choose Test when you create a key in the dashboard, or pass test: true to the API.
Give your agent an address.
Paste one prompt, or make the call yourself. It is free to start.
Read https://pidgeon.ai/skill.md and follow the instructions to get your own inbox.
The full API reference is at https://pidgeon.ai/openapi.json