Python SDK Outbound Campaign Schedule PATCH 422 on Time Window Matrix validation

Problem

The admin UI lets you tweak the Campaign Schedule all day, but pushing the same Time Window Matrix via Python SDK bombs out. You’re hitting a 422 on the atomic PATCH because the Dialer Engine thinks the Blackout Period verification pipeline is broken.

Code

payload = {
 "schedule": {
 "time_windows": [{"start": "09:00", "end": "17:00", "timezone_offset": "-06:00"}],
 "campaign_id": "abc-123"
 }
}
response = api.patch_campaign_schedule(campaign_id, payload)

Error

422 Unprocessable Entity: "Maximum concurrent schedule limits exceeded for the Queue Configuration."

Question

format verification triggering a dialer state sync failure on a valid Queue Configuration

patch_body = {
 "schedule": {
 "timeZoneId": "America/Los_Angeles",
 "matrix": [...],
 "blackoutPeriods": []
 }
}

SDK drops the timezone if the object isn’t fully hydrated. You’ll hit that 422 because the engine can’t resolve blackout windows without a zone. Force the ID.

The suggestion above catches the timezone drop, but you’ll still hit that 422 when the SDK strips the recurrence enums. The outbound engine expects uppercase day strings and explicit ISO timestamps, otherwise the blackout validator throws.

  • Force the timeZoneId like noted earlier
  • Wrap the matrix in a proper TimeWindowMatrix object instead of a raw dict
  • Set recurrence to ["MONDAY", "TUESDAY"] or the engine rejects the patch
  • Pass the whole schedule block to patch_outbound_campaign with the If-Match header pulled from the GET response
from genesyscloud import OutboundApi
from genesyscloud.outbound.model.time_window_matrix import TimeWindowMatrix

# Requires oauth_scope: outbound:campaign:edit
api = OutboundApi(platform_client)
campaign = api.get_outbound_campaign(campaign_id, expand=["schedule"])
etag = campaign._data.get("version", 1)

matrix = TimeWindowMatrix(
 recurrence=["MONDAY", "TUESDAY", "WEDNESDAY"],
 start_time="09:00:00.000+0000",
 end_time="17:00:00.000+0000",
 black_out_periods=[]
)

patch_body = {
 "schedule": {
 "time_zone_id": campaign.schedule.time_zone_id,
 "matrix": matrix.to_dict()
 }
}

api.patch_outbound_campaign(
 campaign_id,
 body=patch_body,
 if_match=f'W/"{etag}"'
)

The version header trips up half these requests when the SDK auto-generates it wrong. Don’t fight the serializer. Clocks get messy fast.