Programmatic Wrap-up Code Assignment via Conversations API

Hey everyone,

I’m hitting a snag while trying to automate wrap-up code assignment for voice interactions using the Genesys Cloud Conversations API. We’ve got a Terraform setup that handles most of our org structure, but we need a post-interaction hook to enforce compliance codes based on call disposition data we’re capturing in our internal DB.

The goal is straightforward: once the conversation state moves to ENDED, I want to programmatically apply the correct wrap-up code. I’ve been testing this using the Python SDK, specifically calling post_conversations_interactions_wrapup on the conversations_api instance. Here’s the snippet I’m working with:

try:
 wrapup_body = models.Wrapup(
 code_id="my-wrapup-code-id-from-api",
 custom_disposition={"score": 5}
 )
 api_response = api_instance.post_conversations_interactions_wrapup(
 conversation_id=conv_id,
 wrapup=wrapup_body,
 async_request=True
 )
 print(f"Wrap-up set: {api_response}")
except ApiException as e:
 print(f"Exception: {e}")

The issue is that this call returns a 202 Accepted immediately, which is expected for async operations. However, when I query the conversation details shortly after, the wrapup object is still empty or shows code_id: null. I’ve waited up to 30 seconds between the call and the check, so it’s not just a race condition in my script.

I’ve verified the code_id is valid by fetching it from get_routing_wrapupcodes. I also tried setting async_request=False, but that seems to timeout or just hang, which isn’t ideal for our webhook handler. Is there a specific state requirement before this endpoint works? I noticed the docs mention the conversation must be in a specific state, but ENDED should qualify.

Also, if I try to call this endpoint while the agent is still in WRAPUP state (before they actually click end), I get a 400 Bad Request saying the conversation isn’t ready. That part makes sense, but the ENDED state isn’t triggering the assignment as expected.

Anyone else automating wrap-up codes this way? Am I missing a required header or a specific payload field that forces the sync? I’m starting to think I might need to poll for a specific status before hitting this endpoint, but that feels clunky. Any insights on the correct flow here would be great. I’ve checked the state drift backups and the config is definitely live.