Contacts

Upsert a Contact

Changed on

Creates a new contact or updates an existing one.

Identifiers — with only linkedin_url, also pass account_id or domain.

Duplicate resolution — matched against existing contacts by email (case-insensitive), then linkedin_url. A match is updated in place, otherwise a contact is created. Unlike POST /contacts, a duplicate identifier is not a 409. The exception: if the identifiers resolve to two different contacts on the same account, neither can be updated and a 409 is returned.

Update by id — with id, that contact is updated as on PATCH /v1/contacts/{contact_id} and never created; an unknown id returns 404. This is how to change a contact's email. Null fields are left unchanged; list fields to clear in clear_fields. account_id, domain, location and is_inbound are not accepted with id.

Account resolution priority — when creating: account_id, then domain, then the domain parsed from email.

Enrichment — creating a contact synchronously enriches it and resolves or creates its account, so those requests can take several seconds. Use generous timeouts (10s+) and keep upserts off hot paths.

put/v1/contacts/

Request

  • Base URL
    https://api.monaco.com
  • URL
    https://api.monaco.com/v1/contacts/
  • Auth
    none declared

Request body

is_inboundboolean

Whether the contact is an inbound lead. When true and this request creates a new contact, Monaco records it as a captured inbound lead. Ignored when the request matches an existing contact.

emailstring nullable

Email address of the contact. Either email or linkedin_url is required.

linkedin_urlstring nullable

LinkedIn profile URL (a linkedin.com/in/... URL). Either email or linkedin_url is required.

first_namestring nullable

First name of the contact

last_namestring nullable

Last name of the contact

titlestring nullable

Job title of the contact

phone_numberstring nullable

Phone number of the contact

locationstring nullable

Location of the contact

account_idstring uuid nullable

ID of the account to associate the contact with

domainstring nullable

Domain of the contact's company (used for account resolution)

do_not_contactboolean nullable

Whether the contact has opted out of outreach

notesstring nullable

Notes about the contact

tagsstring[] nullable

Tag IDs for the contact. When the upsert matches an existing contact, replaces its existing tags.

idstring uuid nullable

ID of an existing contact to update. If set, that contact is updated by ID instead of matched by email or linkedin_url, so its email can be changed.

clear_fieldsContactClearableField[] nullable

Fields to clear on the contact. Only applies when id is present.

Example request

{
  "email": "jane@acme.com",
  "linkedin_url": "https://linkedin.com/in/janesmith",
  "first_name": "Jane",
  "last_name": "Smith",
  "title": "VP of Engineering",
  "phone_number": "+1-415-555-0132",
  "location": "San Francisco, CA",
  "domain": "acme.com",
  "notes": "Met at conference in 2025",
  "clear_fields": [
    "notes"
  ]
}

Response

Successful Response

Example response

{
  "data": {
    "id": "con_abc123",
    "account_id": "acc_def456",
    "account_name": "Acme Corp",
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane@acme.com",
    "title": "VP of Engineering",
    "phone_number": "+1-415-555-0132",
    "linkedin_url": "https://linkedin.com/in/janesmith",
    "location": "San Francisco, CA",
    "source": "linkedin",
    "notes": "Met at SaaStr 2025",
    "scoring": {
      "heat_score": "Hot"
    },
    "tags": [
      "Interested",
      "Decision Maker"
    ],
    "created_at": "2025-06-15T10:30:00Z",
    "updated_at": "2025-06-15T10:30:00Z",
    "last_activity_at": "2025-06-15T10:30:00Z",
    "last_activity_type": "outbound_email",
    "last_outbound_at": "2025-06-15T10:30:00Z",
    "last_outbound_type": "email",
    "last_inbound_at": "2025-06-15T10:30:00Z",
    "last_inbound_type": "email"
  }
}

Changes

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status