Guest API typing indicator payloads failing with 400 Bad Request

Hey everyone, I’ve run into a really strange issue with the Web Messaging Guest API when attempting to send real-time typing indicators and read receipts. My application uses the standard OAuth client credentials flow to generate a guest token, which works fine for sending initial text messages. However, when I try to push a typing indicator using the documented endpoint POST /api/v2/webmessaging/guests/{guestId}/messages, the server consistently returns a 400 Bad Request. The payload structure mirrors the official schema, but the response body is vague, stating only invalid_request. I have verified that the guestId is valid and the token has not expired. My current implementation looks like this:

const payload = {
 "type": "typing",
 "content": "",
 "timestamp": new Date().toISOString()
};

await fetch(`${baseUrl}/api/v2/webmessaging/guests/${guestId}/messages`, {
 method: 'POST',
 headers: {
 'Authorization': `Bearer ${guestToken}`,
 'Content-Type': 'application/json'
 },
 body: JSON.stringify(payload)
});

I have tried omitting the content field, changing type to typing_indicator, and even sending a minimal object with just type. All variations result in the same 400 error. Interestingly, if I send a standard text message with type: "text" and valid content, it succeeds immediately. This suggests the issue is specific to the event type validation logic on the backend. I am also seeing intermittent 429s when I retry these requests in a loop, which complicates debugging. I am working from the Asia/Singapore timezone, so latency to the US East endpoints is a factor, but the 400s occur within 50ms, ruling out timeout issues.

Has anyone successfully implemented typing indicators via the REST Guest API? I suspect I might be missing a required header or a specific scope like webmessaging:guest:write that isn’t explicitly documented for event-only payloads. Any insights into the exact JSON structure required for non-text events would be appreciated. I am methodically checking every field against the Swagger spec, but the discrepancy remains.

The quickest way to solve this is… 400 Bad Request means your JSON schema is invalid. The endpoint rejects typing payloads because it expects full message objects. Use the dedicated typing indicator endpoint instead.

POST /api/v2/webmessaging/guests/{guestId}/typing
Content-Type: application/json

{}

Check the API docs. Stop guessing.