Account, Project & Opportunity contacts

New: isPrimary and full contact detail

contacts[] on accounts, projects, and opportunities now returns id, name, title, description, emails, phones, and isPrimary for every contact (previously just id/emails/phones on accounts, and nothing at all on projects/opportunities).

  • isPrimary is true for exactly one contact — the one at the lowest position (the first element you send on create/update). At most one contact is ever primary.
  • Projects and opportunities now return contacts too — their own contacts, independent of and not inherited from the parent account’s. Set them on create/update via the contacts request field, same as accounts. Pass include_contacts=true on GET /projects, GET /projects/search, GET /projects/{project_id}, and the equivalent /opportunities endpoints to include it — same as accounts.
  • POST/PATCH responses always include contacts for accounts, projects, and opportunities — not gated behind include_contacts like GET is.

Notes

  • Account create/update responses previously returned only { id } for contacts immediately after a write — they now always return the full contact detail.

Contact responses

Fixed: missing fields

  • accounts, projects, opportunities, and vendors — a contact’s related records are now split into all four buckets. Previously only accounts and projects were populated; a contact linked to an opportunity or a vendor silently disappeared from the response.
  • PATCH /contacts/{contact_id} previously could return empty accounts/projects even when the contact had existing links — it was trusting a raw write response that didn’t include them. It now includes them after the write, matching POST /contacts.

Projects & Opportunities

Fixed: workflowId returning null after create/update

Creating or updating a project/opportunity with an explicit workflowId (Workflows 2.0) previously came back with workflowId: null in the response, even though the correct phase was assigned correctly. The re-fetch used after every create/update wasn’t selecting the underlying field.

Trades

Updated: trades is now a documented enum

trades on projects and opportunities is validated against a fixed list of trade types (case-insensitive). The docs now show the full accepted list instead of a bare string, on both the request and response schemas.