Update Supplier Contact Info (Email / Central Phone)

Write a supplier's email address and central phone number into P21 — the fields purchasing documents and views read from the supplier's address record.

API: Transaction (POST /api/v2/transaction) · Service: Address · Deep dive: Transaction API · Full schema: Address.json

Where supplier contact info actually lives

supplier.supplier_id shares its id with an address row (address.id = supplier_id). The email and central phone shown for a supplier come from address.email_address and address.central_phone_number — not from the supplier table (its only email-ish columns are email_po_flag / supplier_redemption_email). Verified against a live 2026 system: the supplier's address row carried exactly the values surfaced by purchasing views.

The Address service (window: Address maintenance) is the smallest write surface for these fields — its definition is ~9 KB vs ~70 KB for Supplier, and it needs only the address id as key.

Payload

Status: "New" is the upsert shape — an existing id updates that record (see Status "Existing" is not valid). IgnoreIfEmpty: true on the contact edits means an empty value leaves the stored field untouched — this payload can add or replace contact info but can never blank it.

POST {ui_server}/api/v2/transaction

{
  "Name": "Address",
  "UseCodeValues": false,
  "IgnoreDisabled": true,
  "Transactions": [{
    "Status": "New",
    "DataElements": [
      {
        "Name": "TABPAGE_1.tp_1_dw_1",
        "Type": "Form",
        "Keys": ["id"],
        "Rows": [{ "Edits": [
          { "Name": "id", "Value": "20488", "IgnoreIfEmpty": false }
        ] }]
      },
      {
        "Name": "TABPAGE_3.tp_3_dw_3",
        "Type": "Form",
        "Keys": [],
        "Rows": [{ "Edits": [
          { "Name": "email_address",                "Value": "orders@example.com", "IgnoreIfEmpty": true },
          { "Name": "address_central_phone_number", "Value": "319-555-0100",       "IgnoreIfEmpty": true }
        ] }]
      }
    ]
  }]
}

Field names on the Phone tab (TABPAGE_3.tp_3_dw_3): address_central_phone_number, address_central_fax_number, email_address.

Verify (read-after-write)

Don't trust Summary.Succeeded alone — read the record back (why):

POST {ui_server}/api/v2/transaction/get

{
  "ServiceName": "Address",
  "TransactionStates": [
    { "DataElementName": "TABPAGE_1.tp_1_dw_1", "Keys": [{ "Name": "id", "Value": "20488" }] },
    { "DataElementName": "TABPAGE_3.tp_3_dw_3", "Keys": [{ "Name": "id", "Value": "20488" }] }
  ]
}

The response's TABPAGE_3.tp_3_dw_3 row echoes email_address / address_central_phone_number as stored.

Gotchas (verified live on Play, 2026-07)

Python

import httpx

def update_supplier_contact(ui_server: str, token: str, supplier_id: int,
                            email: str = "", phone: str = "") -> None:
    """Upsert supplier contact fields on the shared address record."""
    payload = {
        "Name": "Address", "UseCodeValues": False, "IgnoreDisabled": True,
        "Transactions": [{
            "Status": "New",
            "DataElements": [
                {"Name": "TABPAGE_1.tp_1_dw_1", "Type": "Form", "Keys": ["id"],
                 "Rows": [{"Edits": [
                     {"Name": "id", "Value": str(supplier_id), "IgnoreIfEmpty": False}]}]},
                {"Name": "TABPAGE_3.tp_3_dw_3", "Type": "Form", "Keys": [],
                 "Rows": [{"Edits": [
                     {"Name": "email_address", "Value": email, "IgnoreIfEmpty": True},
                     {"Name": "address_central_phone_number", "Value": phone,
                      "IgnoreIfEmpty": True}]}]},
            ],
        }],
    }
    resp = httpx.post(
        f"{ui_server}/api/v2/transaction", json=payload,
        headers={"Authorization": f"Bearer {token}",
                 "Accept": "application/json", "Content-Type": "application/json"},
        timeout=60,
    )
    resp.raise_for_status()
    summary = resp.json().get("Summary") or {}
    if summary.get("Failed"):
        raise RuntimeError(f"Address write failed: {resp.text[:300]}")