Mixpanel API Engage

Mixpanel API Engage

Mixpanel의 Engage API는 사용자 프로필(User Profile)을 다루는 핵심 인터페이스예요. 사용자가 이벤트를 보낼 때 함께 쌓이는 인구통계 속성(이름·이메일·부서 같은 프로필 속성)을 만들고, 읽고, 갱신하고, 지우는 전 과정을 HTTP로 처리할 수 있어요. 이벤트에 프로필을 붙여서 "누가" "무엇을" 했는지를 한 눈에 보려면 같은 Distinct ID를 이벤트와 프로필 양쪽에 동일하게 써야 해요. 프로필 생성·갱신은 api.mixpanel.com/engage로, 프로필 조회(세그먼트)는 Query API의 /engage 엔드포인트로 나뉘어요.

출처: User Profile (Mixpanel Docs)

본문

Engage API 개요

User Profile은 이벤트를 수행한 사용자의 인구통계 속성(사용자 프로퍼티)으로 이벤트를 풍부하게 만들어 줘요. 프로필은 선택 사항이라, 일반적으로 이벤트부터 시작하고 필요한 경우에만 프로필을 추가하길 권장해요.

Mixpanel은 내부적으로 프로젝트의 사용자 데이터를 테이블에 저장하는데, 각 행이 한 사용자의 프로필이고 열이 갱신 가능한 사용자 프로퍼티(예: Name, Email, Department)에 해당해요.

Distinct ID Name Email Department
123 Alice [email protected] Engineering
456 Bob [email protected] Product
789 Carol [email protected] Design

사용자 프로필은 사용자를 식별하는 Distinct ID 를 기준으로 이벤트에 조인돼요. 그래서 같은 사용자에 대해 이벤트와 프로필 모두 반드시 같은 Distinct ID를 사용해야 해요.

프로필 생성·갱신은 이벤트 추적과 비슷한 방식으로 할 수 있어요 — SDK, HTTP Engage API, Warehouse Connector, 또는 연동 파트너를 통해서요. 이때 프로필의 진실 원천(source of truth, 보통 애플리케이션 DB나 CRM)에 최대한 가까운 곳에서 추적하길 권장해요. 서버사이드 추적의 전형적인 방식은, 서버에서 시간별·일별 스크립트를 돌려 DB의 프로필 목록을 뽑아 Mixpanel로 푸시하는 거예요.

프로필 속성 연산자 (Operators)

Engage API는 프로필 갱신용 연산자를 제공해요. 프로퍼티를 설정·수정하거나, 숫자를 증감시키거나, 목록(list)을 조작하거나, 프로퍼티를 제거하는 방식으로 나뉘어요.

프로퍼티 설정

  • $set — 프로필 프로퍼티를 설정하거나, 이미 있으면 값을 갱신해요.
  • $set_once — Mixpanel에 아직 없을 때만 프로퍼티를 설정해요. 기존 값을 덮어쓰지 않게 보장해서 "첫 로그인 날짜" 같은 값에 유용해요.

숫자 프로퍼티 갱신

  • $add — 숫자 사용자 프로퍼티 값을 증감시켜요 (그룹 프로필에서는 미지원). 양수면 증가, 음수면 감소를 뜻하고, 프로퍼티가 없으면 전달한 값이 초기값으로 설정돼요.

목록 프로퍼티 갱신

  • $union — 주어진 값을 목록(List) 타입 프로퍼티에 병합하고 중복 값을 없애요.
  • $append — 목록 타입 사용자 프로퍼티 끝에 값을 추가해요 (그룹 프로필에서는 미지원). 중복을 검사하지 않아요.
  • $remove — 목록 타입 프로퍼티에서 값을 제거해요.

프로퍼티 제거

  • $unset — 프로필에서 특정 프로퍼티를 제거해요.
  • $delete — 프로필의 모든 프로퍼티를 제거해요.

$set 연산자로 사용자 프로필을 갱신하는 예시 코드예요.

# Fill this out. You can get it from https://mixpanel.com/settings/project
PROJECT_TOKEN = ""

import json
import requests


def get_users_from_database():
    # Replace this with code that reads users from your database or CRM.
    # Note: $name and $email are optional, but useful properties that automatically populate certain parts of our UI when Mixpanel detects them.
    return [
        {"user_id": "123", "$name": "Alice", "$email": "[email protected]", "department": "engineering"},
        {"user_id": "456", "$name": "Bob", "$email": "[email protected]", "department": "product"},
        {"user_id": "789", "$name": "Carol", "$email": "[email protected]", "department": "design"}
    ]

def transform_to_mp_format(user):
    """Transform the above into Mixpanel's format"""
    # It's important to set this to the same distinct_id that you use when tracking events.
    # We recommend using the primary key of your users' table for this.
    distinct_id = user.pop("user_id")

    # Note: we set `$ip` to 0 here to tell Mixpanel not to look up the IP of this user.
    return {"$distinct_id": distinct_id, "$token": PROJECT_TOKEN, "$ip": "0", "$set": user}


users = get_users_from_database()
profiles = [transform_to_mp_format(u) for u in users]

# We recommend calling this API with batches of 200 user profiles to do this at scale.
resp = requests.post(
    "https://api.mixpanel.com/engage",
    params={"verbose": "2"},
    headers={"Content-Type": "application/json"},
    data=json.dumps(profiles)
)

print(resp.json())

확장 시에는 한 번에 200개 프로필씩 배치로 호출하길 권장해요. 주의할 점은 이벤트에 사용하는 것과 같은 distinct_id(보통 사용자 테이블의 기본 키)를 프로필에도 사용해야 이벤트와 프로필이 올바르게 조인된다는 거예요.

프로필 조회 (Query / 세그먼트)

저장된 프로필을 검색·세그먼트하려면 Query API의 /engage 엔드포인트(POST)를 사용해요. 조건에 맞는 사용자(또는 그룹) 목록을 반환하죠.

  • where — 사용자(또는 그룹)를 필터링할 조건식이에요.
  • distinct_id / distinct_ids — 특정 프로필 하나 또는 여러 개(distinct_ids=["id1", "id2"] 형식)를 직접 조회할 수 있어요.
  • data_group_id — 그룹 프로필을 조회할 때 쓰는 그룹 키 ID예요.

각 요청은 최대 page_size 개의 레코드만 반환해요. 더 많은 레코드를 원하면 같은 where 파라미터를 쓰되, 첫 응답에서 받은 session_id를 그대로 넘기고 page 값을 응답보다 1 크게 잡아 반복 호출하면 돼요. 전체 레코드를 가져오는 전형적인 알고리즘 예시예요.

// Get the first page of data associated with our selector expression
this_page = query_api(where=YOUR_SELECTOR_EXPRESSION)
do_something_with_response(this_page)

// If we get fewer records than the page_size returned with our results,
// then there are no more records to get. Otherwise, keep querying for additional pages.
while (length of this_page.results) >= this_page.page_size:
    next_page_number = this_page.page + 1
    this_page = query_api(where=YOUR_SELECTOR_EXPRESSION, session_id=this_page.session_id, page=next_page_number)
    do_something_with_response(this_page)

Query API는 시간당 60회 쿼리최대 5개 동시 쿼리라는 레이트 리밋이 있어요. 인증은 서비스 계정(Service Account) 또는 프로젝트 시크릿(Project Secret)으로 하고, 서비스 계정을 쓰면 project_id가 필요해요.

프로필 조회 (UI)와 삭제

Mixpanel UI에서도 특정 사용자의 프로필을 볼 수 있어요. Data > Users 탭에서 모든 추적 사용자 목록과 주요 속성을 확인하고, 필터(distinct ID·이메일·기타 프로퍼티)로 사용자를 좁힌 뒤 해당 사용자를 클릭하면 프로필 화면이 열려요. 프로필 화면은 두 영역으로 나뉘는데, 가운데/오른쪽 패널은 Activity Feed(사용자가 보낸 이벤트를 역시간순으로 나열, 기본 최근 30일)이고 왼쪽 패널은 User Profile Properties(사용자가 누구인지를 설명하는 변경 가능한 속성들)예요.

프로필 삭제는 Users 페이지에서 하거나, Engage API $delete로 프로그램 방식으로 할 수 있어요. 사용자 프로필을 삭제하면 사용자 속성 데이터만 사라지고 이벤트는 남아요 — 익명 사용자로 남은 것처럼 계속 프로젝트에 나타나요.

알아두면 좋은 점

  • 프로필 속성 vs 이벤트 속성: 이름·이메일·도메인 같은 인구통계 속성은 사용자 프로퍼티로, 그 외 대부분은 이벤트 프로퍼티로 추적하길 권장해요.
  • Mixpanel은 이벤트와 프로필을 내부적으로 별도 테이블에 저장하고 쿼리 시점에 조인해요. 그래서 이벤트를 먼저 추적한 뒤 프로필을 넣어도 과거 이벤트에도 소급 적용되고, 이벤트는 항상 프로필의 최신 상태와 조인돼요.
  • 사용자 프로필당 최대 2000개 프로퍼티까지 가능하고, 프로퍼티 이름은 최대 255자(초과분은 잘림)예요. 길어지면 $unset으로 정리하면 돼요.
  • Mixpanel은 프로필 갱신 시각을 담는 $last_seen(Updated at) 프로퍼티를 자동 유지해요. 이벤트가 발생했다고 바뀌지 않고, 프로필이 갱신될 때만 변해요.

더 알아보기 (Learn more)