400 Bad Request - Callback API

Hey all,

Been chasing my tail on this one for a couple of days. Scheduled callbacks are failing intermittently - not a complete outage, but enough to tank the customer experience. It’s hitting the PATCH /api/v2/conversations/callbacks endpoint, and we’re getting a 400 Bad Request back. The weird part is the error message isn’t consistent. Sometimes it’s “Invalid estimatedWaitTimeSeconds”, other times it just says “Bad Request” with no details.

Not 100% sure but I think it’s tied to the EWT calculation. We’re using the recommended formula from the docs - (current queue length / agent count) * average handle time - and rounding up to the nearest second. The queue length is dynamic, obviously, and we pull AHT from the historical reporting API. Everything looks right in the data, but the platform’s rejecting the values.

We’ve got retry logic built in - three attempts, exponential backoff - but it’s not helping much. The retry logic just keeps re-submitting the same request with the same EWT, so it fails every time. Feels like the issue isn’t transient.

Small thing, we’re on the latest GA release of Genesys Cloud, using the Node.js SDK v7. The Architect flow is pretty straightforward - a simple IVR surveys for callback preference, then pushes the data to the API. The callback data object looks something like this:

{
 "contactId": "123e4567-e89b-12d3-a456-426614174000",
 "phoneNumber": "+818012345678",
 "scheduledTime": "2024-02-29T14:00:00.000Z",
 "estimatedWaitTimeSeconds": 60,
 "callbackReasonCode": "SCHEDULED_CALLBACK"
}

The EWT is the problem child. We’ve tested limiting the EWT to a maximum of 3600 seconds (1 hour), thinking it might be a platform limit, but the errors still come through. I’ve also temporarily hardcoded the EWT to 60 seconds as a workaround - that’s stopped the immediate failures but obviously isn’t a long-term solution.

Anyone else running into this? Is there a hidden limit on the EWT value I’m missing? The documentation isn’t clear. The callback UX is getting hammered.

Oh gosh, that sounds really annoying! I think I remember someone mentioning that estimatedWaitTimeSeconds needs to be a whole number - not a decimal, silly me. We’ve had trouble with that before, and it’s easy to miss. Also, are you sure the callback’s to number is in E.164 format? I always get those mixed up… sorry if that’s a dumb question!

1 Like

tbh, that endpoint is… sensitive. iirc, the estimatedWaitTimeSeconds thing is a classic - it has to be an integer, but that’s not always the whole story.

we’ve seen it throw a 400 with no helpful message when the callbackId is already in use. it’s… dumb. the API doesn’t exactly scream at you about it, it just fails.

try checking if you’re reusing callbackId values. it’s easy to do if you’re generating them on the client-side without tracking. if you’re generating them server-side, double-check the logic.

here’s an example payload that usually works (imo, cleaner than what most people send):

{
 "to": "+15551234567",
 "from": "+15559876543",
 "estimatedWaitTimeSeconds": 60,
 "callbackId": "unique-id-here-uuid-v4-or-something",
 "callbackUrl": "https://your-callback-endpoint.com"
}

also, double-check the callbackUrl. it needs to be publicly accessible (no auth, afaik) and return a 200 OK. we spent a day on that one last month.

and just to be sure - what version of the API are you using? (should be v2, obviously, but just checking.)

1 Like

The inconsistent error message points to payload validation - it’s not a single issue. The note above is right about estimatedWaitTimeSeconds needing to be an integer, but that’s only half of it. We’ve seen this with the to number too; the API expects E.164, but it’s surprisingly strict about formatting. No spaces, plus sign first, country code required - the usual.

Long story short, validate everything against the schema. The documentation doesn’t explicitly list all the required fields, which is annoying, but the API will return a 400 with a different message for each missing or invalid parameter. Here’s a sample payload, which might highlight what you’re missing:

{
 "to": "+15551234567",
 "from": "+15557891234",
 "scheduledCallbackTime": "2024-03-15T14:00:00Z",
 "estimatedWaitTimeSeconds": 60,
 "callbackReasonCode": "callback_scheduled"
}

It’s subtle but those field names are case sensitive, too.

That’s right - the payload validation is the key here, and the earlier post’s point about being strict is spot on. We hit a similar thing a while back when pushing callbacks from a Lambda - it’s easy to miss a formatting rule.

Just adding to that, we’ve found that the callbackPriorityType field can be a sneaky one too. It’s not always obvious, but if that’s set to something invalid, it’ll happily accept the rest of the payload and then give you a really unhelpful 400.

Also, are you building the JSON payload directly in your code, or are you using a templating engine of some sort? We’ve been doing more of the payload construction in CloudFormation these days - it’s a bit of a pain to set up, but it keeps things consistent and prevents those kinds of formatting errors. Something like this:

Resources:
 CallbackPayloadTemplate:
 Type: AWS::CloudFormation::StackSet
 Properties:
 TemplateBody: |
 {
 "to": "${PhoneNumber}",
 "estimatedWaitTimeSeconds": "${WaitTime}",
 "callbackPriorityType": "STANDARD"
 }

Does the error happen consistently for the same phone number, or is it more random?