8분

Marketo Engage REST API를 사용하여 마케팅 운영 업무를 자동화하는 방법을 살펴보세요. 이 문서에서는 Marketo Engage 관리자가 활용할 수 있는 일반적인 사용 사례를 다룹니다. 여기에는 캠페인 생성 간소화, 원치 않는 데이터 변경 사항 되돌리기, 참여 인사이트를 실행 가능한 영업 활동으로 전환하는 방법 등이 포함됩니다.

저는 응용 및 계산 수학 분야에서 경력을 쌓았는데, 이는 대부분의 Marketo Engage 실무자들과 차별화되는 특징입니다. 마케팅 운영 부서에서 일하기 시작하면서 많은 업무가 자동화될 수 있다는 것을 깨달았습니다. 자동화를 통해 업무 효율성을 높이고 경력 성장을 가속화할 수 있습니다. API를 사용하여 일상 업무를 자동화하면 운영 업무에 얽매이지 않고 더욱 전략적인 업무에 집중할 수 있습니다.

이 문서에서는 제가 Marketo Engage REST API를 어떻게 사용했는지, 그리고 가장 좋아하는 세 가지 사용 사례를 통해 그 강력한 기능을 어떻게 보여주는지 공유하겠습니다. REST API가 Marketo Engage에서 효율성을 향상하 고 전략적인 업무에 집중할 수 있도록 돕는 방법을 보여드리겠습니다.

자, 이제 안전띠를 매고 이러한 비즈니스 시나리오에서 REST API를 어떻게 활용하는지 알아볼 준비를 하세요.

사용 사례 1: 캠페인 만들기 간소화

Marketo Engage는 마케팅 운영을 확장하는 데 강력한 도구로, 프로세스를 간소화하는 데 도움이 되는 템플릿과 토큰을 제공합니다. 하지만 솔직히 말해서, 여전히 많은 수작업이 필요합니다. 마케팅 운영에 종사하는 분이라면 프로그램 복제, 토큰 업데이트, 스마트 캠페인 활성화에 상당한 시간을 할애하고 계실 것입니다.

일주일에 몇 개의 캠페인만 관리한다면 따라잡을 수 있을지도 모릅니다. 하지만 수십 개, 심지어 수백 개의 캠페인을 관리해야 한다면 모든 것을 수동으로 처리하는 것은 현실적으로 불가능합니다. 실수는 언제든 발생할 수 있으며, 캠페인 전체의 일관성을 유지하는 것은 매우 어려운 일입니다. 여기서 Marketo Engage REST API가 등장합니다. 이러한 반복적인 작업을 자동화하면 시간을 절약하고 오류를 줄이며 모든 마케팅 활동의 일관성을 유지할 수 있습니다.

REST API를 사용하면 모든 것을 체계적이고 일관되게 유지하면서 전체 프로그램을 빠르게 복제할 수 있습니다. Marketo Engage에 가장 숙련된 실무자라도 실수를 할 수 있으며, 자동화는 위험을 최소화하고 데이터 무결성을 유지하는 데 도움이 됩니다.

이 프로세스를 통해 마케팅 요구에 맞춰 캠페인을 맞춤 설정할 수 있습니다. REST API를 사용하면 캠페인 구조의 일관성을 유지하면서 토큰과 같은 주요 요소를 수정할 수 있습니다.

아래 데모 비디오를 시청하시면 제공된 샘플 코드를 사용하고 조직의 요구에 맞게 조정하는 방법을 설명합니다.
아래 비디오에서 오프라인으로 사용할 수 있는 코드를 “샘플 코드” 섹션에서 찾아보세요.

사용 사례 2: 원치 않는 데이터 변경 내용 되돌리기

이러한 시나리오를 상상해 보세요. 마케터들이 Marketo Engage에 리드 목록을 업로드해 달라고 긴급히 요청했을 때,이미 업무에 쫓기고 있는 상황입니다. 빨리 처리했는데, SDR로부터 데이터가 완전히 잘못되었다는 연락을 받았습니다! 직책이 잘못되었고, 이전 리드가 덮어씌워졌으며, 모든 것이 엉망입니다.

이는 모든 마케팅 운영 전문가에게 악몽과 같은 상황입니다. 이러한 오류를 수동으로 수정하는 데는 몇 시간, 심지어 며칠이 걸릴 수 있습니다. 하지만 걱정하지 마세요. Marketo Engage의 REST API가 해결책을 제시합니다. 데이터 타임머신처럼 원치 않는 변경 내용을 손쉽게 추적하고 되돌릴 수 있습니다.

REST API를 사용하면 최근 데이터 값 변경 로그를 가져오고, 잘못된 업데이트를 식별하며, 몇 단계만으로 원본 정보를 복원할 수 있습니다. 데이터를 수동으로 정리하는 대신, 롤백 프로세스를 자동화하여 데이터베이스의 정확성과 안정성을 유지할 수 있습니다.

아래 비디오에서는 REST API를 사용하여 잘못된 데이터 가져오기를 되돌리고 Marketo Engage 인스턴스를 오류 없이 깔끔하게 유지하는 방법을 살펴보겠습니다.
NOTE
이 방법은 간단한 데이터 되돌리기 사례에만 적용됩니다. 변경 사항이 많을 경우, 되돌릴 적절한 값을 선택하기 위해 더욱 정교한 논리가 필요합니다.
아래 비디오에서 오프라인으로 사용할 수 있는 코드를 “샘플 코드” 섹션에서 찾아보세요.

사용 사례 3: 인사이트를 판매 작업으로 변환

영업 팀에게 맥락은 무엇보다 중요합니다. 특히 리드가 MQL(Marketing Qualified Lead)로 전환된 이유를 파악하는 데 있어서는 더욱 그렇습니다. 하지만 이러한 적격성 평가의 기반이 되는 데이터는 참여 지표에 묻혀 있는 경우가 많아 영업 담당자가 고객의 이야기를 직접 분석하는 데 많은 시간이 소요됩니다.

이러한 어려움을 해결하기 위해 자동화가 도입되었습니다. Marketo Engage를 AI와 통합하면 참여 데이터를 명확하고 실행 가능한 인사이트로 변환하여 영업 팀이 진정으로 중요한 것, 즉 거래 성사에 집중할 수 있도록 지원합니다.

Marketo Engage REST API를 사용하면 최근 참여 활동을 가져오고 생성형 AI를 통해 처리하여 간단한 요약을 생성한 다음, 이 요약을 Marketo Engage에 다시 푸시하여 가시성을 확보할 수 있습니다. 즉, 영업 담당자는 더 이상 리드가 MQL로 전환된 과정을 파악하기 위해 개인의 활동 로그를 꼼꼼히 살펴볼 필요가 없습니다. 대신, AI가 생성한 리드 여정에 대한 간단한 설명을 받게 됩니다. 요약에는 고객이 관심을 보인 제품 또는 서비스와 브랜드를 위해 수행한 주요 활동이 포함됩니다.

Salesforce에서 영업 팀이 이 정보에 즉시 액세스할 수 있게 되면, 자신감을 가지고 대화에 임하고, 접근 방식을 개인화하며, 궁극적으로 더 많은 거래를 더 빨리 성사시킬 수 있습니다.

이 사용 사례는 리드가 MQL로 전환될 때 REST API를 사용하도록 설계되었습니다. 따라서 한 번에 하나의 리드에 대해서만 실행됩니다. 더 많은 리드에 이 방법을 적용하려는 경우 대량 API가 더 적합합니다.

아래 비디오를 통해 이 설정이 실제로 어떻게 작동하는지 살펴보겠습니다.
IMPORTANT
개인 데이터를 대규모 언어 모델(LLM)로 전송하기 전에 조직의 관련 규정 준수 담당자와 상의하여 관련 법률 및 규정을 준수해야 합니다.
아래 비디오에서 오프라인으로 사용할 수 있는 코드를 “샘플 코드” 섹션에서 찾아보세요.

핵심 사항

Marketo Engage REST API를 사용하여 마케팅 운영을 간소화하는 방법은 여기까지입니다.

REST API를 활용할 수 있는 세 가지 강력한 사용 사례를 살펴보았습니다.

  1. 캠페인 복제를 자동화하여 수동 작업을 줄이고 일관성을 유지합니다.
  2. 원치 않는 데이터 변경 사항을 추적하고 되돌려 정리 시간을 절약합니다.
  3. 영업 팀에 MQL에 대한 즉각적인 인사이트를 제공하여 더욱 효과적인 후속 대화를 지원합니다.

이러한 자동화 기술은 단순히 시간을 절약하는 데 그치지 않습니다. 정확성을 보장하고 데이터 무결성을 유지하며 마케팅 팀과 영업 팀이 더욱 효율적으로 작업할 수 있도록 지원합니다.

REST API를 사용하면 이렇게 많은 가능성을 볼 수 있다는 사실에 압도될 수도 있으니, 몇 가지 팁을 알려드리겠습니다.

이 글이 도움이 되셨다면 Adobe Experience League에서 더 많은 동료의 인사이트와 모범 사례를 확인해 보세요. 읽어주셔서 감사합니다. 자동화를 즐겁게 활용하세요!

샘플 코드

캠페인 만들기 간소화

import requests
import pandas as pd
import json
import urllib.parse
MUNCHKIN = "YOUR-MUNCHKIN-ID"
client_id = "YOUR-CLIENT-ID"
client_secret= "YOUR-CLIENT-SECRET"
def get_access_token():
    global client_id
    global client_secret
    global MUNCHKIN
    params={'grant_type': 'client_credentials', 'client_id': client_id, 'client_secret': client_secret}
    headers={'Accept-Encoding': 'gzip'}
    url="https://"+MUNCHKIN+".mktorest.com/identity/oauth/token"
    response=requests.get(url=url,params=params,headers=headers)
    data=response.json()
    return data['access_token']
5
5-7
templateID=5200
folderName="Active Webinars"
programName="WB-2025-02-20-Test"
eventName="Webinar Test"
eventDate="2025-02-20"
18
url="https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/folder/byName.json"
token=get_access_token()
params={"name": folderName,
        "type": "Folder",
        "Content-Type": "application/x-www-form-urlencoded"}
headers={'Authorization': 'Bearer ' + token}
response=requests.get(url=url,params=params, headers=headers)
data=response.json()
print(data)
folderID=data['result'][0]["id"]
23

url="https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/program/

↪"+str(templateID)+"/clone.json"

token=get_access_token()

params={"Content-Type": "application/x-www-form-urlencoded"}

headers={'Authorization': 'Bearer ' + token}

body="name="+programName+"&folder={'id':"+str(folderID)+",'type':'Folder'}" url=url+"?"+body

response=requests.post(url=url,params=params,headers=headers)

data=response.json()

print(data)

programid=data['result'][0]['id']

33
url="https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/smartCampaigns.json"
token=get_access_token()
params={"Content-Type": "application/x-www-form-urlencoded"}
headers={'Authorization': 'Bearer ' + token}
body="folder={'id':"+str(programid)+",'type':'Program'}"
url=url+"?"+body
response=requests.get(url=url, params=params, headers=headers)
data=response.json()
campaigns=[]
for campaign in data['result']:
    campaigns.append(campaign['id'])
print(campaigns)
43
for campaign in campaigns:
    url="https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/smartCampaign/
    ↪"+str(campaign)+"/activate.json"
    token=get_access_token()
    headers={'Authorization': 'Bearer ' + token}
    response=requests.post(url=url,headers=headers)
    data=response.json()
    print(data)
55
url = "https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/folder/
 ↪"+str(programid)+"/tokens.json"
token=get_access_token()
headers = {
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/x-www-form-urlencoded"}
payload = {
           "name": "Webinar Name",
           "value": eventName,
           "type": "text",
           "folderType": "Program"}
response = requests.post(url, headers=headers, data=payload)
data=response.json()
data
63
url = "https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/folder/
 ↪"+str(programid)+"/tokens.json"
token=get_access_token()
headers = {
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/x-www-form-urlencoded"}
payload = {
           "name": "Webinar Date",
           "value": eventDate,
           "type": "date",
           "folderType": "Program"}
response = requests.post(url, headers=headers, data=payload)
data=response.json()
data
77

원치 않는 데이터 변경 내용 되돌리기

import pandas as pd
import csv
import json
import ast
import requests
import math
MUNCHKIN = "YOUR-MUNCHKIN-ID"
client_id = "YOUR-CLIENT-ID"
client_secret= "YOUR-CLIENT-SECRET"
def get_access_token():
    global client_id
    global client_secret
    global MUNCHKIN
    params={'grant_type': 'client_credentials',
            'client_id': client_id,
            'client_secret': client_secret}
    headers={'Accept-Encoding': 'gzip'}
    url="https://"+MUNCHKIN+".mktorest.com/identity/oauth/token" response=requests.get(url=url,params=params,headers=headers)
    data=response.json()
    return data['access_token']
7
7-9
sinceDate="2025-04-22T00:00:00-00:00"
field='Job Title'
fieldRest='Title'
listID=299
21
url="https://"+MUNCHKIN+".mktorest.com/rest/v1/activities/pagingtoken.json"
token=get_access_token()
params={'sinceDatetime':sinceDate}
headers={'Authorization': 'Bearer ' + token,}
response=requests.get(url=url,params=params, headers=headers)
data=response.json()
nextPageToken=data['nextPageToken']
data
25
url="https://"+MUNCHKIN+".mktorest.com/rest/v1/activities.json"
params={'nextPageToken': nextPageToken,
        'activityTypeIds':[13],
        'listId': listID}
headers={'Authorization': 'Bearer ' + token,}
response=requests.get(url=url,params=params,headers=headers)
data=response.json()
print(data) act=data['result']
while data['moreResult']==True:
      nextPageToken=data['nextPageToken']
      token=get_access_token()
      params={'nextPageToken': nextPageToken,
              'activityTypeIds':[13],
              'listId': listID}
      headers={'Authorization': 'Bearer ' + token}
      response=requests.get(url=url,params=params,headers=headers) data=response.json()
      print(data)
      act=act+(data['result'])
33
df=pd.json_normalize(act)
df=df[df['primaryAttributeValue']==field]
df=df.sort_values('activityDate')
df=df.reset_index()
df=df.drop(columns=['index'])
df
51
df1=pd.json_normalize(df['attributes'])
i=4
while i<len(df1.columns):
      df1=df1.drop(columns=[list(df1.columns)[i]])
      i=i+1
df1.columns=['New_Value','Old_Value','Reason','Source']
df1.New_Value=pd.json_normalize(df1.New_Value)['value']
df1.Old_Value=pd.json_normalize(df1.Old_Value)['value']
df1.Reason=pd.json_normalize(df1.Reason)['value']
df1.Source=pd.json_normalize(df1.Source)['value']
57
df=pd.merge(df,df1,left_index=True, right_index=True)
df=df.drop(columns=['attributes'])
df=df.drop_duplicates(subset='leadId', keep="first")
67
df
70
df.to_excel("dataToCorrect.xlsx")
71
ids=df[df.columns.to_list()[2]].to_list()
camposval=df['Old_Value'].to_list()
for i in range(len(camposval)):
         if camposval[i] == None:
            camposval[i] = 'NULL'
STEP=300
a=math.ceil(len(ids)/STEP)
i=0
while i<a:
     tempids=ids[i*STEP:(i+1)*STEP]
     tempcamposval=camposval[i*STEP:(i+1)*STEP]
     params={'action': 'updateOnly',
             'lookupField': 'id',
             'input':[]}
j=0
while j<len(tempids):
     lead={'id':tempids[j],
           fieldRest:tempcamposval[j]}
     params['input'].append(lead)
     j=j+1
     token=get_access_token()
     url="https://"+MUNCHKIN+".mktorest.com/rest/v1/leads.json"
     headers={'content-type': 'application/json', 'Authorization': 'Bearer ' + token }
     i=i+1
     response=requests.post(url=url,data=json.dumps(params), headers=headers)
     print(response.json()['result'])
72

인사이트를 판매 활동으로 변환

importrequests
import pandas as pd
import json
fromdatetimeimportdatetime, timedelta
MUNCHKIN = "YOUR-MUNCHKIN-ID"
client_id = "YOUR-CLIENT-ID"
client_secret= "YOUR-CLIENT-SECRET"
defget_access_token():
        globalclient_id
        globalclient_secret
        globalMUNCHKIN
        params={'grant_type': 'client_credentials',
                          'client_id': client_id,
                          'client_secret': client_secret}
        headers={'Accept-Encoding': 'gzip'}
        url="https://"+MUNCHKIN+".mktorest.com/identity/oauth/token"
        response=requests.get(url=url,params=params,headers=headers)
        data=response.json()
        return data['access_token']
5
5-7
leadid="1007244"
ndays=60
gptAPIKey="Bearer␣
  ↪sk-proj-ne6OZggjgQhQU6XcG0ocHNPNzBvOOULTkk8a-75Y75rHKS-vyztxPYq0OLaFsnhtGivx9bVUNoT3BlbkFJH
fieldName="MktoPersonNotes"
20
today = datetime.today()
sinceDate = today - timedelta(days=ndays)
sinceDate = sinceDate.strftime("%Y-%m-%dT00:00:00")
25
url="https://"+MUNCHKIN+".mktorest.com/rest/v1/activities/pagingtoken.json"
token=get_access_token()
params={'sinceDatetime': sinceDate}
headers={'Authorization': 'Bearer ' + token}
response=requests.get(url=url,params=params,headers=headers)
data=response.json()
nextPageToken=data['nextPageToken']
28
data
35
access_token=get_access_token()
def get_lead_activities(token, lead_id, firstToken):
    url = f"https://"+MUNCHKIN+".mktorest.com/rest/v1/activities.json"
    params={
             "leadId": lead_id,
             "activityTypeIds": "1,2,3,10,11,34,104",
             "nextPageToken": firstToken
             }
    headers={'Authorization': 'Bearer ' + token}
    activities = []
    more_results = True
    while more_results:
         response = requests.get(url, params=params, headers=headers)
         data = response.json()
         if 'result' in data:
             activities.extend(data['result'])
             more_results = data.get('moreResult', False)
         if more_results:
             params["nextPageToken"] = data['nextPageToken']
    return activities
all_activities = get_lead_activities(access_token, leadid,nextPageToken)
all_activities = str(all_activities).replace('"', "'")
activities=all_activities
activities
36
def send_to_chatgpt(activities):
    url = "https://api.openai.com/v1/chat/completions"
    headers = {
         "Authorization": gptAPIKey,
         "Content-Type": "application/json"
         }
    prompt = """Analyze the following lead activities and explain the␣
↪activities that contributed to this lead being marked as MQL so a␣
↪salesperson knows how they should approach the client, including which␣
↪product or service this lead is most interested in and any other relevant␣
↪insights. Include relevant URLs on form fills:""" +activities+""" – Remember␣
↪this will only be read by a salesperson, so don't use technical␣
↪explanations, just your best summary. Keep your response limited to 100␣
↪words."""
    data = {
         "model": "gpt-4o-mini",
         "messages": [{"role": "user", "content": prompt}],
         "max_tokens": 250
         }
         response = requests.post(url, headers=headers, json=data)
         return response.json()
gpt_response = send_to_chatgpt(activities)['choices'][0]['message']['content']
gpt_response
60
def update_marketo_field(lead_id, field_name, gpt_response):
       access_token=get_access_token()
       url = "https://"+MUNCHKIN+".mktorest.com/rest/v1/leads.json"
       headers = {
               "Content-Type": "application/json",
               'Authorization': 'Bearer ' + token
               }
       payload = {
                "action": "updateOnly",
                "lookupField": "id",
                "input":[
                        {
                         "id": int(lead_id),
                          field_name: gpt_response
                         }
                      ]
                   }
       response = requests.post(url, headers=headers, json=payload)
       return response.json()
update_response = update_marketo_field(leadid, fieldName, gpt_response)
update_response
83