Updating a query-builder card via the API

I'm trying to use the API to update a card that was built via the query builder. My goal is to only update the "data" section, while keeping the "Filter", "Summarize", etc. values the same as before. I have the ID of the new sql question that is meant to be plugged in to the "data" section of this query builder card.

My code is included below. It's running without errors, but when I check my target card its "data" section has been wiped clean instead of updated. Some of its summary and filter values are gone too. Any ideas on how to handle this correctly?

I'm on v0.53.2, self-hosted open source.

def get_card(card_id):
    res = requests.get(f"{BASE_URL}/api/card/{card_id}", headers=HEADERS)
    res.raise_for_status()
    return res.json()

def update_card(card_id, payload):
    res = requests.put(f"{BASE_URL}/api/card/{card_id}", headers=HEADERS, json=payload)
    res.raise_for_status()
    return res.json()

def replace_card_source(target_card_id, source_card_id):
    # 1) Fetch the full card object
    card = get_card(target_card_id)

    # 2) Update only the source in the dataset_query
    dq = card["dataset_query"]
    dq["query"]["source-query"] = [source_card_id]

    # 3) Build the PUT payload by mirroring all the fields Metabase expects
    payload = {
        "name":                   card["name"],
        "description":            card["description"],
        "collection_id":          card["collection_id"],
        "dashboard_id":           card["dashboard_id"],
        "dashboard_tab_id":       card.get("dashboard_tab_id"),
        "collection_position":    card["collection_position"],
        "cache_ttl":              card["cache_ttl"],
        "archived":               card["archived"],
        "enable_embedding":       card["enable_embedding"],
        "embedding_params":       card["embedding_params"],
        "display":                card["display"],
        "type":                   card["type"],
        "view_count":             card["view_count"],
        "collection_preview":     card["collection_preview"],
        "visualization_settings": card["visualization_settings"],
        "result_metadata":        card["result_metadata"],
        "parameters":             card["parameters"],
        "parameter_mappings":     card["parameter_mappings"],
        "dataset_query":          dq,
    }

    # 4) Push it back
    update_card(target_card_id, payload)
    print(f"✅ Card {target_card_id} now sources from question {source_card_id}")
  
replace_card_source(TARGET_CARD_ID, SOURCE_CARD_ID)