Developer guide
Keys
Each system has its own key, sent as Authorization: Bearer …. Test keys (tb_test_…) send only to the test recipients; live keys (tb_live_…) send to anyone in WRLD's Microsoft 365.
Send a message
POST /api/v1/messages with to.person (a work email) and either text (Teams markdown) or card (an Adaptive Card, version 1.6 or lower). Derek puts your system's name above it. Every POST needs an Idempotency-Key: repeat a request with the same key and nothing is sent twice.
curl -X POST https://teams.wchi.app/api/v1/messages \
-H "Authorization: Bearer tb_test_…" \
-H "Idempotency-Key: po-2026-114-approval" \
-H "Content-Type: application/json" \
-d '{"to": {"person": "jv@wrldcapitalholdings.com"},
"text": "Approval needed: **PO-2026-114**"}'{
"message": {
"id": "6f1c…",
"status": "sent",
"mode": "test",
"to": { "person": "jv@wrldcapitalholdings.com" },
"created_at": "2026-11-11T03:10:00.000Z",
"status_at": "2026-11-11T03:10:01.000Z"
}
}Check a message
GET /api/v1/messages/{id}. The full description is at /api/v1/openapi.json.
Errors
| Code | HTTP | Meaning |
|---|---|---|
| invalid_key | 401 | The API key is missing, revoked or not recognised. |
| idempotency_key_required | 400 | Every POST needs an Idempotency-Key header (1 to 255 characters). |
| invalid_request | 400 | The request body doesn't match the API. |
| recipient_not_found | 400 | No one in WRLD's Microsoft 365 has that address. |
| test_recipient_not_allowed | 403 | A test key sends only to the test recipients. |
| not_found | 404 | No such message for this integration. |
| request_in_progress | 409 | A request with this Idempotency-Key is still being sent. Retry shortly. |
| idempotency_key_reused | 422 | This Idempotency-Key was already used with a different request. |
| rate_limited | 429 | Too many messages from this integration. Retry after the time given. |
| teams_rejected | 502 | Teams refused the message. |
| teams_unavailable | 502 | Teams or Microsoft Graph didn't answer. Retry with the same Idempotency-Key. |
| sending_paused | 503 | Sending is paused. |
| teams_app_not_ready | 503 | Derek isn't in WRLD's Teams app catalog yet. |
| internal | 500 | Something went wrong on Derek's side. |