{"openapi":"3.1.0","info":{"title":"ChatAd Agent API","version":"1.0.0","description":"OpenAI(ChatGPT)·Google·Meta 광고를 대화로 관리하는 ChatAd 의 에이전트용 API 입니다. 토큰 없이 부르는 손님 도구(체험 도구는 하루 3회, X-ChatAd-Agent 머리글로 이름을 밝힌 봇은 5회)와 Bearer 토큰으로 부르는 회원 도구가 같은 주소 모양을 씁니다. 회원 도구 중 금액이 걸린 것은 2단입니다: 첫 호출은 바뀔 내용과 confirm_token 만 돌려주고, 사용자의 답을 받은 뒤 같은 인자 + confirm_token 으로 다시 부릅니다. 가입·결제·약관 동의는 사용자가 직접 합니다. MCP 로도 같은 일을 합니다: https://mcp.gmp.ai/chatad?guest=1 (손님) · https://mcp.gmp.ai/chatad (회원).","contact":{"name":"BizSpring","url":"https://chatad.kr/#contact"}},"servers":[{"url":"https://chatad.kr"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"start_signup 이나 OAuth 로 받은 access_token"}}},"paths":{"/api/agent/tools/about_chatad":{"post":{"operationId":"about_chatad","summary":"ChatAd 가 무엇이고 무엇을 할 수 있는지, 로그인 없이 쓸 수 있는 것과 가입 뒤에 쓸 수 있는 것, 가입하는 방법을 돌려준다. 처음 들어왔으면 이것부터 부른다. 하루 한도에 들지 않는다.","description":"ChatAd 가 무엇이고 무엇을 할 수 있는지, 로그인 없이 쓸 수 있는 것과 가입 뒤에 쓸 수 있는 것, 가입하는 방법을 돌려준다. 처음 들어왔으면 이것부터 부른다. 하루 한도에 들지 않는다.","tags":["guest"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"로그인 없이 쓰는 체험 도구 하루 3회(이름을 밝힌 봇은 5회) 초과"}}}},"/api/agent/tools/get_plans":{"post":{"operationId":"get_plans","summary":"요금제와 결제 방법을 돌려준다. 🔴 금액이 확정되지 않았으면 prices_confirmed 가 false 로 온다. 그때는 금액을 지어내지 말고 「확정 전」이라고 안내한다. 하루 한도에 들지 않는다.","description":"요금제와 결제 방법을 돌려준다. 🔴 금액이 확정되지 않았으면 prices_confirmed 가 false 로 온다. 그때는 금액을 지어내지 말고 「확정 전」이라고 안내한다. 하루 한도에 들지 않는다.","tags":["guest"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"로그인 없이 쓰는 체험 도구 하루 3회(이름을 밝힌 봇은 5회) 초과"}}}},"/api/agent/tools/get_guides":{"post":{"operationId":"get_guides","summary":"광고를 시작할 때 필요한 준비물과 절차를 적은 가이드 목록(OpenAI·Google·Meta 광고 시작 가이드 등)을 돌려준다. 하루 한도에 들지 않는다.","description":"광고를 시작할 때 필요한 준비물과 절차를 적은 가이드 목록(OpenAI·Google·Meta 광고 시작 가이드 등)을 돌려준다. 하루 한도에 들지 않는다.","tags":["guest"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"로그인 없이 쓰는 체험 도구 하루 3회(이름을 밝힌 봇은 5회) 초과"}}}},"/api/agent/tools/check_ad_readiness":{"post":{"operationId":"check_ad_readiness","summary":"웹사이트 첫 화면을 읽어 광고 전환 측정 준비가 되어 있는지 본다(Google 태그 관리자 · GA4 · Meta 픽셀 · 사이트 응답). 🔴 로그인 없이 MCP 세션마다 50회, 세션 번호가 없으면 하루 3회(이","description":"웹사이트 첫 화면을 읽어 광고 전환 측정 준비가 되어 있는지 본다(Google 태그 관리자 · GA4 · Meta 픽셀 · 사이트 응답). 🔴 로그인 없이 MCP 세션마다 50회, 세션 번호가 없으면 하루 3회(이름을 밝힌 봇은 5회)까지다.","tags":["guest"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"분석할 웹사이트 주소. https:// 는 빼도 된다"}},"required":["url"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"로그인 없이 쓰는 체험 도구 하루 3회(이름을 밝힌 봇은 5회) 초과"}}}},"/api/agent/tools/analyze_site":{"post":{"operationId":"analyze_site","summary":"광고할 웹사이트를 분석한다. 제목·설명·소제목·본문 앞부분·주요 하위 페이지·광고 목적 추천·문맥 힌트 후보, 그리고 GEOcare 가 연결돼 있으면 AI 답변에 아직 안 나오는 질문. 캠페인을 설계할 때 먼저 부른","description":"광고할 웹사이트를 분석한다. 제목·설명·소제목·본문 앞부분·주요 하위 페이지·광고 목적 추천·문맥 힌트 후보, 그리고 GEOcare 가 연결돼 있으면 AI 답변에 아직 안 나오는 질문. 캠페인을 설계할 때 먼저 부른다. 공개된 페이지만 분석한다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"url":{"type":"string","description":"광고할 웹사이트 주소 (https://…)"}},"required":["workspace_owner","url"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/draft_campaign":{"post":{"operationId":"draft_campaign","summary":"웹사이트와 하루 총 예산으로 OpenAI·Google·Meta 광고 캠페인 초안(예산 배분 · 핵심 메시지 · 키워드나 문맥 힌트 · 광고 문구)을 만든다. 🔴 초안만 만든다. 광고주 계정에는 아무것도 만들지 않는","description":"웹사이트와 하루 총 예산으로 OpenAI·Google·Meta 광고 캠페인 초안(예산 배분 · 핵심 메시지 · 키워드나 문맥 힌트 · 광고 문구)을 만든다. 🔴 초안만 만든다. 광고주 계정에는 아무것도 만들지 않는다. 🔴 예산은 사용자가 말한 금액만 쓴다. 🔴 로그인 없이 MCP 세션마다 50회, 세션 번호가 없으면 하루 3회(이름을 밝힌 봇은 5회)까지다.","tags":["guest"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"분석할 웹사이트 주소. https:// 는 빼도 된다"},"daily_budget_krw":{"type":"integer","description":"하루 총 예산(원). 사용자가 말한 금액 그대로"},"media":{"type":"array","items":{"type":"string","enum":["openai_ads","google_ads","meta_ads"]},"description":"초안을 만들 광고. 안 주면 셋 다"}},"required":["url","daily_budget_krw"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"로그인 없이 쓰는 체험 도구 하루 3회(이름을 밝힌 봇은 5회) 초과"}}}},"/api/agent/tools/start_signup":{"post":{"operationId":"start_signup","summary":"사용자 대신 ChatAd 가입을 시작한다. 🔴 사용자가 가입하겠다고 답한 뒤에만 부른다. 방법이 둘이다. method=email_code: 사용자 메일로 6자리 코드가 간다. 사용자에게 코드를 물어 complete","description":"사용자 대신 ChatAd 가입을 시작한다. 🔴 사용자가 가입하겠다고 답한 뒤에만 부른다. 방법이 둘이다. method=email_code: 사용자 메일로 6자리 코드가 간다. 사용자에게 코드를 물어 complete_signup 에 넣는다. method=device: 확인 주소와 짧은 코드가 온다. 사용자에게 그 주소를 열어 로그인·승인하라고 안내하고, check_signup 으로 승인됐는지 본다. 어느 쪽이든 약관 동의와 본인 확인은 사용자가 직접 한다.","tags":["guest"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"method":{"type":"string","enum":["email_code","device"]},"email":{"type":"string","description":"method=email_code 일 때 필요한 사용자 이메일"},"client_name":{"type":"string","description":"이 에이전트의 이름(예: Claude, ChatGPT, Grok, Meta AI). 승인 화면에 보인다"}},"required":["method"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"로그인 없이 쓰는 체험 도구 하루 3회(이름을 밝힌 봇은 5회) 초과"}}}},"/api/agent/tools/complete_signup":{"post":{"operationId":"complete_signup","summary":"email_code 방식의 마지막 단계. 사용자가 불러 준 6자리 코드로 가입·로그인을 마치고 access_token 을 받는다. 그 토큰을 Authorization: Bearer 로 붙여 회원 MCP(https:/","description":"email_code 방식의 마지막 단계. 사용자가 불러 준 6자리 코드로 가입·로그인을 마치고 access_token 을 받는다. 그 토큰을 Authorization: Bearer 로 붙여 회원 MCP(https://mcp.gmp.ai/chatad, ?guest 없이)를 부른다.","tags":["guest"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"code":{"type":"string","description":"메일로 받은 6자리 숫자"},"client_name":{"type":"string"}},"required":["email","code"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"로그인 없이 쓰는 체험 도구 하루 3회(이름을 밝힌 봇은 5회) 초과"}}}},"/api/agent/tools/check_signup":{"post":{"operationId":"check_signup","summary":"device 방식에서 사용자가 승인했는지 본다. 승인됐으면 access_token 이 온다. 아직이면 status 가 pending 이니 interval 초 뒤에 다시 부른다.","description":"device 방식에서 사용자가 승인했는지 본다. 승인됐으면 access_token 이 온다. 아직이면 status 가 pending 이니 interval 초 뒤에 다시 부른다.","tags":["guest"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"device_code":{"type":"string"}},"required":["device_code"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"429":{"description":"로그인 없이 쓰는 체험 도구 하루 3회(이름을 밝힌 봇은 5회) 초과"}}}},"/api/agent/tools/skill_list":{"post":{"operationId":"skill_list","summary":"이 서버를 어떤 순서로 쓰는지, 무엇을 오해하기 쉬운지 적어 둔 절차서 목록. 🔴 막히거나 처음이면 도구를 더 뒤지지 말고 이것부터 부른다. 인자도 비용도 없다.","description":"이 서버를 어떤 순서로 쓰는지, 무엇을 오해하기 쉬운지 적어 둔 절차서 목록. 🔴 막히거나 처음이면 도구를 더 뒤지지 말고 이것부터 부른다. 인자도 비용도 없다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/skill_get":{"post":{"operationId":"skill_get","summary":"절차서 한 편을 읽는다. skill_list 가 준 id 를 그대로 넣는다. 인자도 비용도 없다.","description":"절차서 한 편을 읽는다. skill_list 가 준 id 를 그대로 넣는다. 인자도 비용도 없다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"절차서 번호. skill_list 가 준 id"}},"required":["id"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/get_me":{"post":{"operationId":"get_me","summary":"이 연결이 어느 계정 것인지, 어떤 워크스페이스를 열어 두었는지, 각각에서 지금 무엇이 되고 안 되는지를 한 번에 준다. 🔴 막히면 이것부터 부른다.","description":"이 연결이 어느 계정 것인지, 어떤 워크스페이스를 열어 두었는지, 각각에서 지금 무엇이 되고 안 되는지를 한 번에 준다. 🔴 막히면 이것부터 부른다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_workspaces":{"post":{"operationId":"list_workspaces","summary":"이 연결로 만질 수 있는 워크스페이스 목록. 다른 도구의 workspace_owner 인자에 넣을 값이 여기서 온다.","description":"이 연결로 만질 수 있는 워크스페이스 목록. 다른 도구의 workspace_owner 인자에 넣을 값이 여기서 온다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/get_plan":{"post":{"operationId":"get_plan","summary":"이 계정의 지금 요금제와 요금제 목록·결제 방법을 준다. 🔴 prices_confirmed 가 false 면 금액이 확정 전이다. 금액을 지어내지 말고 「확정 전」이라고 안내한다. 워크스페이스를 고르지 않아도 된다","description":"이 계정의 지금 요금제와 요금제 목록·결제 방법을 준다. 🔴 prices_confirmed 가 false 면 금액이 확정 전이다. 금액을 지어내지 말고 「확정 전」이라고 안내한다. 워크스페이스를 고르지 않아도 된다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/get_usage":{"post":{"operationId":"get_usage","summary":"이 연결(로그인한 사람)의 오늘 MCP 도구 사용 횟수를 도구별로 준다. 한도에 가까운지 볼 때 부른다. 워크스페이스를 고르지 않아도 된다.","description":"이 연결(로그인한 사람)의 오늘 MCP 도구 사용 횟수를 도구별로 준다. 한도에 가까운지 볼 때 부른다. 워크스페이스를 고르지 않아도 된다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/request_upgrade":{"post":{"operationId":"request_upgrade","summary":"유료 요금제 전환을 신청한다. 🔴 2단이다. 먼저 confirm_token 없이 부르면 신청할 내용만 오고 아무것도 접수되지 않는다. 사용자에게 보여 주고 답을 받은 뒤 같은 인자와 confirm_token 으로 ","description":"유료 요금제 전환을 신청한다. 🔴 2단이다. 먼저 confirm_token 없이 부르면 신청할 내용만 오고 아무것도 접수되지 않는다. 사용자에게 보여 주고 답을 받은 뒤 같은 인자와 confirm_token 으로 다시 부르면 접수된다. 🔴 결제는 하지 않는다. 접수되면 담당자가 결제 방법(무통장입금·카드)과 세금계산서를 안내한다. 🔴 사용자가 전환하겠다고 말했을 때만 부른다.","tags":["member · 2단 승인"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["basic","standard","team","enterprise"]},"billing":{"type":"string","enum":["yearly","monthly"],"description":"결제 주기. 안 주면 yearly(카드결제가 열리기 전에는 연 결제를 권한다)"},"note":{"type":"string","description":"담당자에게 전할 말(선택). 사용자가 말한 것만"},"confirm_token":{"type":"string","description":"2단 확인표. 처음에는 비워 둔다. 그러면 바뀔 내용만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다"}},"required":["plan"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/get_briefing":{"post":{"operationId":"get_briefing","summary":"오늘의 아침 브리핑. KST 어제 하루의 광고비·클릭·전환을 광고별로 합치고 앞 7일 평균과 견줘, 에이전트가 찾은 확인할 일(게재 중단·예산 초과·전환 끊김 등)을 함께 준다. 「오늘 광고 어때」 류의 질문이면 이","description":"오늘의 아침 브리핑. KST 어제 하루의 광고비·클릭·전환을 광고별로 합치고 앞 7일 평균과 견줘, 에이전트가 찾은 확인할 일(게재 중단·예산 초과·전환 끊김 등)을 함께 준다. 「오늘 광고 어때」 류의 질문이면 이것부터 부른다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"refresh":{"type":"boolean","description":"참이면 지금 수치로 다시 정리한다. 평소에는 비워 둔다(이미 정리된 것을 준다)"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_findings":{"post":{"operationId":"list_findings","summary":"확인할 일. 에이전트가 브리핑을 정리하며 찾은 일 목록. 일마다 근거 수치와 캠페인 번호가 있다. status 를 안 주면 처리할 일(open)만 준다.","description":"확인할 일. 에이전트가 브리핑을 정리하며 찾은 일 목록. 일마다 근거 수치와 캠페인 번호가 있다. status 를 안 주면 처리할 일(open)만 준다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"status":{"type":"string","enum":["open","done","dismissed","expired","all"],"description":"open(처리할 일) · done(처리함) · dismissed(넘김) · expired(지남) · all"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/resolve_finding":{"post":{"operationId":"resolve_finding","summary":"확인할 일 하나를 처리함(done) 또는 넘김(dismiss)으로 표시한다. 🔵 기록만 바꾸고 광고는 바꾸지 않는다. 실제 조치(일시중지 등)는 set_status 같은 도구로 먼저 한 뒤에 부른다.","description":"확인할 일 하나를 처리함(done) 또는 넘김(dismiss)으로 표시한다. 🔵 기록만 바꾸고 광고는 바꾸지 않는다. 실제 조치(일시중지 등)는 set_status 같은 도구로 먼저 한 뒤에 부른다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"finding_id":{"type":"string","description":"get_briefing 이나 list_findings 가 준 finding_id"},"op":{"type":"string","enum":["done","dismiss"]},"note":{"type":"string","description":"무엇을 했는지 한 줄 (선택)"}},"required":["workspace_owner","finding_id","op"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/get_conversion_diagnostic":{"post":{"operationId":"get_conversion_diagnostic","summary":"OpenAI 광고의 전환이 왜 잡히지 않는지 읽기만 하며 진단한다. 전환 측정 설정·CAPI 등록 증거·OpenAI Ads 전환 인정·ChatAd 측정 유입/전환을 함께 보고, 확인된 원인과 아직 단정할 수 없는 것","description":"OpenAI 광고의 전환이 왜 잡히지 않는지 읽기만 하며 진단한다. 전환 측정 설정·CAPI 등록 증거·OpenAI Ads 전환 인정·ChatAd 측정 유입/전환을 함께 보고, 확인된 원인과 아직 단정할 수 없는 것을 구분한다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"days":{"type":"integer","description":"진단 구간 일수 (1~31, 기본 7). KST 어제까지 본다."}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_campaigns":{"post":{"operationId":"list_campaigns","summary":"캠페인 목록과 게재 중인지 여부. OpenAI 광고와 Google 광고를 한 목록에 주고 줄마다 service 를 적는다. 무엇을 만지기 전에 반드시 먼저 부른다.","description":"캠페인 목록과 게재 중인지 여부. OpenAI 광고와 Google 광고를 한 목록에 주고 줄마다 service 를 적는다. 무엇을 만지기 전에 반드시 먼저 부른다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"service":{"type":"string","enum":["openai_ads","google_ads","meta_ads","daangn_ads"],"description":"OpenAI·Google·당근 가운데 하나만 볼 때. 안 주면 OpenAI 와 Google 전부. 🔴 당근(daangn_ads)은 조회만 되며, 당근이 준 값을 그대로 싣는다"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_product_feeds":{"post":{"operationId":"list_product_feeds","summary":"OpenAI 광고주 계정의 상품 피드 목록과, 이 계정에 상품 피드 기능이 열려 있는지(feed_access). 피드마다 국가·통화·광고 대상 상품 수·SFTP 연결 여부를 준다. 조회만 하며 광고와 피드를 바꾸지 ","description":"OpenAI 광고주 계정의 상품 피드 목록과, 이 계정에 상품 피드 기능이 열려 있는지(feed_access). 피드마다 국가·통화·광고 대상 상품 수·SFTP 연결 여부를 준다. 조회만 하며 광고와 피드를 바꾸지 않는다. 🔴 feed_access 가 granted 가 아니면 상품 피드 캠페인을 만들 수 없다. 그때는 note 를 그대로 안내한다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/current_settings":{"post":{"operationId":"current_settings","summary":"한 캠페인의 지금 예산과 이름, 그 아래 광고그룹의 지금 입찰가. 금액을 바꾸기 전에 부른다. 광고그룹 번호도 여기서 온다.","description":"한 캠페인의 지금 예산과 이름, 그 아래 광고그룹의 지금 입찰가. 금액을 바꾸기 전에 부른다. 광고그룹 번호도 여기서 온다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"}},"required":["workspace_owner","campaign_id"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/campaign_performance":{"post":{"operationId":"campaign_performance","summary":"한 캠페인의 최근 성과. 노출·클릭·클릭률·지출·전환을 준다. 🔴 전환이 0 이어도 「전환이 없는 서비스」가 아니라 전환 측정을 아직 안 이었을 수 있다. conversions_note 를 보고 그대로 안내한다.","description":"한 캠페인의 최근 성과. 노출·클릭·클릭률·지출·전환을 준다. 🔴 전환이 0 이어도 「전환이 없는 서비스」가 아니라 전환 측정을 아직 안 이었을 수 있다. conversions_note 를 보고 그대로 안내한다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"},"days":{"type":"integer","description":"며칠치 (1~31, 기본 7)"}},"required":["workspace_owner","campaign_id"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/ad_group_performance":{"post":{"operationId":"ad_group_performance","summary":"광고그룹별 성과. 노출·클릭·클릭률·지출·클릭당비용·전환을 그룹마다 나눠 준다. campaign_id 를 주면 그 캠페인 안의 그룹들이, ad_group_id 를 주면 그 그룹 하나가 온다. 🔴 어느 소재가 잘 나","description":"광고그룹별 성과. 노출·클릭·클릭률·지출·클릭당비용·전환을 그룹마다 나눠 준다. campaign_id 를 주면 그 캠페인 안의 그룹들이, ad_group_id 를 주면 그 그룹 하나가 온다. 🔴 어느 소재가 잘 나가는지 보려면 이것 말고 creative_performance 를 쓴다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"},"ad_group_id":{"type":"string","description":"광고그룹 번호. current_settings 나 ad_group_performance 가 준 ad_group_id 를 그대로 쓴다"},"days":{"type":"integer","description":"며칠치 (1~31, 기본 7)"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/creative_performance":{"post":{"operationId":"creative_performance","summary":"소재별 성과. 노출·클릭·클릭률·지출·클릭당비용·전환을 소재마다 나눠 준다. ad_group_id 를 주면 그 그룹의 소재들이, campaign_id 를 주면 그 캠페인의 소재 전부가, creative_id 를 주면","description":"소재별 성과. 노출·클릭·클릭률·지출·클릭당비용·전환을 소재마다 나눠 준다. ad_group_id 를 주면 그 그룹의 소재들이, campaign_id 를 주면 그 캠페인의 소재 전부가, creative_id 를 주면 그 소재 하나가 온다. 어느 문구·그림이 잘 먹히는지 견줄 때 쓴다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"},"ad_group_id":{"type":"string","description":"광고그룹 번호. current_settings 나 ad_group_performance 가 준 ad_group_id 를 그대로 쓴다"},"creative_id":{"type":"string","description":"소재 번호. list_creatives 나 creative_performance 가 준 ad_id 를 그대로 쓴다"},"days":{"type":"integer","description":"며칠치 (1~31, 기본 7)"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/compare_campaigns":{"post":{"operationId":"compare_campaigns","summary":"모든 캠페인의 최근 성과를 한 번에 견준다. OpenAI 광고와 Google 광고를 함께 주고 줄마다 service 를 적는다. '제일 잘 나온 게 뭐야' 같은 물음에 쓴다.","description":"모든 캠페인의 최근 성과를 한 번에 견준다. OpenAI 광고와 Google 광고를 함께 주고 줄마다 service 를 적는다. '제일 잘 나온 게 뭐야' 같은 물음에 쓴다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"days":{"type":"integer","description":"며칠치 (1~31, 기본 7)"},"service":{"type":"string","enum":["openai_ads","google_ads","meta_ads"],"description":"OpenAI 광고만 볼지 Google 광고만 볼지. 안 주면 연결된 것 전부"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_creatives":{"post":{"operationId":"list_creatives","summary":"이 캠페인에서 지금 게재되는 소재의 제목·설명·연결 주소·심사 상태. 소재 번호도 여기서 온다.","description":"이 캠페인에서 지금 게재되는 소재의 제목·설명·연결 주소·심사 상태. 소재 번호도 여기서 온다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"}},"required":["workspace_owner","campaign_id"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/why_not_serving":{"post":{"operationId":"why_not_serving","summary":"이 캠페인의 광고가 왜 게재되지 않는지 세 층(캠페인·광고그룹·소재)을 위에서부터 살펴본다. blocked_ads 에 게재되지 않는 소재를 한 벌씩 담아 준다. 어느 소재가 어느 광고그룹에 있고, 게재 상태가 무엇이","description":"이 캠페인의 광고가 왜 게재되지 않는지 세 층(캠페인·광고그룹·소재)을 위에서부터 살펴본다. blocked_ads 에 게재되지 않는 소재를 한 벌씩 담아 준다. 어느 소재가 어느 광고그룹에 있고, 게재 상태가 무엇이고, 심사 중인지 거절됐는지, 지난번 게재를 시도했을 때 무엇으로 거절당했는지(last_refused)까지 온다. OpenAI 광고는 계정 하루 지출 한도(account_spend_limit)도 함께 본다. 한도에 도달하면 캠페인 예산이 남아도 모든 캠페인의 게재가 멈춘다. 「게재되지 않는 광고를 찾아 달라」는 말에 이 도구를 부른다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"}},"required":["workspace_owner","campaign_id"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_change_history":{"post":{"operationId":"list_change_history","summary":"OpenAI Ads 광고주 계정의 변경 기록을 최근 것부터 읽는다. 누가(actor) 무엇을(object·changes) 언제(at) 바꿨는지 온다. ChatAd 가 바꾼 것뿐 아니라 OpenAI 광고 관리자 화면에","description":"OpenAI Ads 광고주 계정의 변경 기록을 최근 것부터 읽는다. 누가(actor) 무엇을(object·changes) 언제(at) 바꿨는지 온다. ChatAd 가 바꾼 것뿐 아니라 OpenAI 광고 관리자 화면에서 사람이 직접 바꾼 것도 들어온다. 「누가 예산을 바꿨나」「어제 무엇이 바뀌었나」를 물으면 부른다. campaign_id 로 좁힐 수 있다. 읽기만 한다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"선택. 이 캠페인의 변경만. list_campaigns 가 준 번호"},"days":{"type":"number","description":"최근 며칠. 기본 7, 최대 90"},"limit":{"type":"number","description":"최대 몇 건. 기본 20, 최대 100"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_custom_audiences":{"post":{"operationId":"list_custom_audiences","summary":"OpenAI Ads 광고주 계정에 올라가 있는 맞춤 잠재고객(고객 명단) 목록을 읽는다. 이름·상태·일치한 사용자 규모(범위)만 온다. 🔴 명단을 만들거나 바꾸는 길은 없다. 고객 명단은 개인정보라 ChatAd 와","description":"OpenAI Ads 광고주 계정에 올라가 있는 맞춤 잠재고객(고객 명단) 목록을 읽는다. 이름·상태·일치한 사용자 규모(범위)만 온다. 🔴 명단을 만들거나 바꾸는 길은 없다. 고객 명단은 개인정보라 ChatAd 와 MCP 로는 다루지 않고, OpenAI 광고 관리자 화면에서 하시라고 안내한다. 읽기만 한다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/get_job_status":{"post":{"operationId":"get_job_status","summary":"값을 바꾼 도구가 돌려준 작업 번호로 그 처리의 결과를 다시 본다. 응답을 못 받았을 때 같은 일을 또 시키지 말고 이것으로 확인한다.","description":"값을 바꾼 도구가 돌려준 작업 번호로 그 처리의 결과를 다시 본다. 응답을 못 받았을 때 같은 일을 또 시키지 말고 이것으로 확인한다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"job_id":{"type":"string","description":"값을 바꾼 도구가 돌려준 job_id"}},"required":["workspace_owner","job_id"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/set_status":{"post":{"operationId":"set_status","summary":"게재를 시작하거나 일시중지한다. 캠페인·광고그룹·소재 셋 다 된다. 번호를 하나만 넣으면 그 층을 만진다. 🔴 게재 시작(activate)만 2단이다. 돈이 나가기 시작하므로, 처음에는 confirm_token 없","description":"게재를 시작하거나 일시중지한다. 캠페인·광고그룹·소재 셋 다 된다. 번호를 하나만 넣으면 그 층을 만진다. 🔴 게재 시작(activate)만 2단이다. 돈이 나가기 시작하므로, 처음에는 confirm_token 없이 불러 「지금 상태 → 바뀔 상태」와 예산을 받고, 사용자에게 보여 준 뒤 답을 받아야 두 번째를 부른다. 일시중지(pause)는 한 번에 처리된다. 🔴 세 층이 모두 게재 중이어야 광고가 게재된다. why_not_serving 이 어느 층을 바꿔야 하는지 알려 준다. 보관과 삭제는 할 수 없다. 사용자가 분명히 말했을 때만 부른다.","tags":["member · 2단 승인"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"},"ad_group_id":{"type":"string","description":"광고그룹 하나만 켜거나 끌 때. current_settings 나 why_not_serving 이 준 번호. OpenAI 광고와 Google 광고 다 됩니다"},"ad_id":{"type":"string","description":"소재 하나만 켜거나 끌 때. list_creatives 가 준 번호. OpenAI 광고와 Google 광고 다 됩니다"},"service":{"type":"string","enum":["openai_ads","google_ads","meta_ads"],"description":"광고그룹·소재 번호가 어느 광고 것인지. Meta 광고 세트·광고를 켜고 끌 때 meta_ads 를 넣는다(Meta 와 Google 번호는 둘 다 숫자라 모양으로 구별되지 않는다). 캠페인에는 필요 없다"},"state":{"type":"string","enum":["activate","pause"],"description":"게재 시작 activate · 일시중지 pause"},"confirm_token":{"type":"string","description":"2단 확인표. 게재 시작(activate)에만 쓴다. 처음에는 비워 둔다. 그러면 지금 상태와 예산만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다. 일시중지에는 필요 없다"}},"required":["workspace_owner","state"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/set_budget":{"post":{"operationId":"set_budget","summary":"캠페인 예산 금액을 바꾼다. Google 캠페인이면 일예산이다. 🔴 2단이다. 처음에는 confirm_token 없이 불러 바뀔 내용을 받고, 사용자에게 보여 준 뒤 답을 받아야 두 번째를 부른다. 🔴 사용자가 ","description":"캠페인 예산 금액을 바꾼다. Google 캠페인이면 일예산이다. 🔴 2단이다. 처음에는 confirm_token 없이 불러 바뀔 내용을 받고, 사용자에게 보여 준 뒤 답을 받아야 두 번째를 부른다. 🔴 사용자가 말한 금액만 쓴다.","tags":["member · 2단 승인"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"},"amount_krw":{"type":"integer","description":"원 단위. 사용자가 말한 금액 그대로"},"confirm_token":{"type":"string","description":"2단 확인표. 처음에는 비워 둔다. 그러면 바뀔 내용만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다"}},"required":["workspace_owner","campaign_id","amount_krw"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/set_bid":{"post":{"operationId":"set_bid","summary":"광고그룹 입찰가를 바꾼다. 입찰가는 캠페인이 아니라 광고그룹에 붙는다 (current_settings 로 광고그룹 번호를 먼저 받는다). 여러 광고그룹을 같은 값으로 바꿀 때는 ad_group_ids 에 번호를 모아","description":"광고그룹 입찰가를 바꾼다. 입찰가는 캠페인이 아니라 광고그룹에 붙는다 (current_settings 로 광고그룹 번호를 먼저 받는다). 여러 광고그룹을 같은 값으로 바꿀 때는 ad_group_ids 에 번호를 모아 한 번만 확인받는다. 🔴 2단이다. 🔴 사용자가 말한 금액만 쓴다.","tags":["member · 2단 승인"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"ad_group_id":{"type":"string","description":"광고그룹 번호. 한 곳만 바꿀 때. OpenAI(adgrp_ 로 시작)와 Google(숫자뿐) 둘 다 받으며, 번호 모양으로 어느 광고인지 가른다"},"ad_group_ids":{"type":"array","items":{"type":"string"},"description":"여러 광고그룹을 같은 입찰가로 바꿀 때. 한 번에 20개까지. ad_group_id 와 함께 주면 거절된다. 미리보기에 건별로 지금 값과 바뀔 값이 오고, 반영 결과도 건별로 온다. 한 건씩 보내므로 일부만 반영될 수 있으므로 results 를 그대로 전한다. OpenAI 광고에만 있다"},"amount_krw":{"type":"integer","description":"원 단위. 사용자가 말한 금액 그대로"},"confirm_token":{"type":"string","description":"2단 확인표. 처음에는 비워 둔다. 그러면 바뀔 내용만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다"}},"required":["workspace_owner","amount_krw"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/set_schedule":{"post":{"operationId":"set_schedule","summary":"캠페인의 게재 기간(시작일·종료일)을 바꾼다. 날짜는 YYYY-MM-DD 이고 한국 시간 기준이다 — 종료일로 적은 그날까지 게재된다. 바꾸지 않을 칸은 아예 보내지 않는다. 비우려면 그 칸에 빈 문자열을 넣는다(무","description":"캠페인의 게재 기간(시작일·종료일)을 바꾼다. 날짜는 YYYY-MM-DD 이고 한국 시간 기준이다 — 종료일로 적은 그날까지 게재된다. 바꾸지 않을 칸은 아예 보내지 않는다. 비우려면 그 칸에 빈 문자열을 넣는다(무기한이 된다). 🔴 2단이다. 처음에는 confirm_token 없이 불러 바뀔 내용을 받고, 사용자에게 보여 준 뒤 답을 받아야 두 번째를 부른다. 🔴 사용자가 말한 날짜만 쓴다. 🔴 OpenAI 광고에만 있다.","tags":["member · 2단 승인"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"},"start_date":{"type":"string","description":"시작일 YYYY-MM-DD. 안 주면 시작일은 그대로 둔다. 빈 문자열이면 시작일을 지워 즉시 시작으로 만든다"},"end_date":{"type":"string","description":"종료일 YYYY-MM-DD. 그날까지 게재된다. 안 주면 종료일은 그대로 둔다. 빈 문자열이면 종료일을 지워 중지하실 때까지로 만든다"},"confirm_token":{"type":"string","description":"2단 확인표. 처음에는 비워 둔다. 그러면 바뀔 내용만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다"}},"required":["workspace_owner","campaign_id"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/set_context_hints":{"post":{"operationId":"set_context_hints","summary":"광고그룹의 '대화 맥락 힌트' 를 바꾼다. ChatGPT 광고에서 키워드를 대신하는 값이다. 🔴 OpenAI 광고에만 있다. Google 광고그룹에는 없다.","description":"광고그룹의 '대화 맥락 힌트' 를 바꾼다. ChatGPT 광고에서 키워드를 대신하는 값이다. 🔴 OpenAI 광고에만 있다. Google 광고그룹에는 없다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"ad_group_id":{"type":"string","description":"광고그룹 번호"},"hints":{"type":"array","items":{"type":"string"},"description":"맥락 힌트 목록. 사용자가 말한 것만 넣는다"}},"required":["workspace_owner","ad_group_id","hints"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/create_campaign":{"post":{"operationId":"create_campaign","summary":"캠페인을 새로 만든다. service 로 어느 광고인지 고른다(안 주면 Google 이다). 🔴 일예산이 걸리므로 2단이다. 🔴 일시중지 상태로 만들어져 지출이 시작되지 않는다. 게재를 시작하려면 set_stat","description":"캠페인을 새로 만든다. service 로 어느 광고인지 고른다(안 주면 Google 이다). 🔴 일예산이 걸리므로 2단이다. 🔴 일시중지 상태로 만들어져 지출이 시작되지 않는다. 게재를 시작하려면 set_status 를 따로 부른다. 🔵 만든 뒤에는 create_ad_group 으로 광고그룹을, create_ad 로 소재를 붙여야 게재된다. 🔴 Google 검색 캠페인은 키워드가 없으면 게재되지 않으므로, 만든 뒤 add_keywords 로 등록하시라고 사용자에게 함께 말한다. 🔴 OpenAI 광고는 과금 기준이 「클릭」 으로 만들어지고 **만든 뒤에는 바꿀 수 없다.** 노출 과금이 필요하면 그 사실을 사용자에게 먼저 알린다. 🔴 두 광고 모두 지역을 좁히지 않고 만든다(전 지역). 지역이 필요하면 만든 뒤 따로 좁히시라고 안내한다. 🔴 캠페인은 지우지 못한다. 잘못 만들면 일시중지가 전부다. 이름과 금액을 사용자에게 확인받고 부른다.","tags":["member · 2단 승인"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"name":{"type":"string","description":"캠페인 이름"},"daily_budget_krw":{"type":"integer","description":"원 단위 일예산. 사용자가 말한 금액 그대로. 하루 평균이라 하루에 최대 2배까지 지출될 수 있다"},"service":{"type":"string","enum":["openai_ads","google_ads","meta_ads"],"description":"어느 광고에 만들지. 안 주면 google_ads 다(종전과 같다). 🔴 사용자가 어느 쪽인지 말하지 않았으면 지어내지 말고 물어본다. 만든 캠페인은 지울 수 없다"},"confirm_token":{"type":"string","description":"2단 확인표. 처음에는 비워 둔다. 그러면 바뀔 내용만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다"}},"required":["workspace_owner","name","daily_budget_krw"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/create_ad_group":{"post":{"operationId":"create_ad_group","summary":"광고그룹을 새로 만든다. 🔴 2단이다. 🔴 입찰가는 사용자가 말한 금액만 쓴다. OpenAI 광고에서는 과금 기준이 캠페인에 매여 있어 고르지 않고, 대화 맥락 힌트를 함께 넣을 수 있다. Google 광고에서는","description":"광고그룹을 새로 만든다. 🔴 2단이다. 🔴 입찰가는 사용자가 말한 금액만 쓴다. OpenAI 광고에서는 과금 기준이 캠페인에 매여 있어 고르지 않고, 대화 맥락 힌트를 함께 넣을 수 있다. Google 광고에서는 맥락 힌트가 없는 대신 키워드를 쓰는데, 키워드는 add_keywords 로 등록한다. **Meta 광고**에서는 광고 세트를 만든다. 입찰가(bid_krw)는 넣지 않는다 — 예산과 입찰은 캠페인 것을 쓰고, 타깃(대한민국 · Advantage+)과 지면(페이스북·인스타그램 함께)은 정해져 있다. 판매 목표 캠페인이면 pixel_id 가 필요하다. 캠페인 번호로 어느 광고인지 판단한다. 만든 뒤에는 create_ad 의 posts 로 페이지 게시물 광고를 붙인다.","tags":["member · 2단 승인"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"campaign_id":{"type":"string","description":"캠페인 번호. list_campaigns 로 받은 id 를 그대로 쓴다. OpenAI 광고든 Google 광고든 번호로 어느 쪽인지 안다"},"name":{"type":"string","description":"광고그룹 이름"},"bid_krw":{"type":"integer","description":"원 단위 입찰가. 사용자가 말한 금액 그대로. OpenAI·Google 광고에서 필수이고, Meta 광고에는 넣지 않는다"},"context_hints":{"type":"array","items":{"type":"string"},"description":"대화 맥락 힌트. 사용자가 말한 것만 넣는다. OpenAI 광고에만 있고 Google 광고에서는 무시된다"},"pixel_id":{"type":"string","description":"Meta 판매 목표 캠페인에만 필요한 픽셀 번호. 트래픽 목표에는 넣지 않는다"},"confirm_token":{"type":"string","description":"2단 확인표. 처음에는 비워 둔다. 그러면 바뀔 내용만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다"}},"required":["workspace_owner","campaign_id","name"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/create_ad":{"post":{"operationId":"create_ad","summary":"소재를 만든다. 일시중지 상태로 만들어져 심사에 들어가므로 지출이 시작되지 않는다. 🔴 두 광고 서비스의 소재 규격이 근본부터 다르다. **OpenAI 광고**는 제목 하나·설명 하나·이미지 하나다. title·b","description":"소재를 만든다. 일시중지 상태로 만들어져 심사에 들어가므로 지출이 시작되지 않는다. 🔴 두 광고 서비스의 소재 규격이 근본부터 다르다. **OpenAI 광고**는 제목 하나·설명 하나·이미지 하나다. title·body 를 주고, image_url 을 주면 그 이미지를 쓰며 안 주면 연결 주소에서 찾는다(어디서 가져왔는지가 결과에 적혀 온다). **Google 광고**는 이미지가 없는 텍스트 조합이다. headlines 를 3개 이상, descriptions 를 2개 이상 줘야 하고 Google 이 그때그때 골라 섞는다. 광고그룹 번호로 어느 쪽인지 판단하므로 사용자에게 되묻지 말고 해당하는 칸만 채운다. **Meta 광고**는 이미 게시한 페이스북 페이지 게시물로 만든다. ad_group_id 에 광고 세트 번호를, posts 에 게시물 주소나 「페이지id_게시물id」를 넣으면 게시물마다 광고가 하나씩 만들어진다(한 번에 10개까지, 이름은 name 뒤에 1·2·3… 이 붙는다). title·body·target_url 은 쓰지 않는다. 결과의 rows 에 게시물마다 만들어졌는지와 실패 까닭이 온다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"ad_group_id":{"type":"string","description":"광고그룹 번호"},"name":{"type":"string","description":"소재 이름"},"title":{"type":"string","description":"제목. OpenAI 광고에 쓴다"},"body":{"type":"string","description":"설명. OpenAI 광고에 쓴다"},"target_url":{"type":"string","description":"누르면 갈 주소"},"headlines":{"type":"array","items":{"type":"string"},"description":"Google 광고의 제목 묶음. 3개 이상이어야 하고 각 30자까지다. Google 이 이 가운데 골라 조합하므로 서로 다른 각도로 쓴다. 15개까지 넣을 수 있다"},"descriptions":{"type":"array","items":{"type":"string"},"description":"Google 광고의 설명 묶음. 2개 이상이어야 하고 각 90자까지다. 4개까지 넣을 수 있다"},"image_url":{"type":"string","description":"쓸 이미지의 공개 주소. OpenAI 광고에만 있다. 사용자가 따로 준비한 이미지가 있을 때만 넣는다. 넣으면 연결 주소에서 찾지 않고 이것만 쓰며, 올리지 못하면 소재를 만들지 않고 멈춘다. 한 변 1200화소까지이고 정사각형을 권한다. 🔴 Google 광고에는 이미지 자리가 없어 넣으면 거절된다"},"posts":{"type":"array","items":{"type":"string"},"description":"Meta 광고 전용. 광고로 쓸 페이스북 페이지 게시물. 게시물 주소(facebook.com/페이지번호/posts/게시물번호, permalink.php?story_fbid=…&id=…)나 「페이지id_게시물id」를 넣는다. 🔴 pfbid 로 시작하는 주소는 번호를 읽을 수 없어 거절된다. 그때는 Meta 광고 관리자의 「기존 게시물 사용」에서 게시물 ID를 받아 오시라고 안내한다"},"page_id":{"type":"string","description":"Meta 광고 전용. 페이지 번호. 게시물 주소의 페이지 자리가 이름이거나 게시물 번호만 있을 때 함께 넣는다"}},"required":["workspace_owner","ad_group_id","name"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/edit_ad_creative":{"post":{"operationId":"edit_ad_creative","summary":"이미 있는 소재의 문구와 이미지를 고친다. OpenAI 광고와 Google 광고 다 된다. 소재 번호로 어느 쪽인지 안다. 🔴 고치면 다시 심사에 들어가 그동안 그 광고가 게재되지 않는다. 그 사실을 사용자에게 함","description":"이미 있는 소재의 문구와 이미지를 고친다. OpenAI 광고와 Google 광고 다 된다. 소재 번호로 어느 쪽인지 안다. 🔴 고치면 다시 심사에 들어가 그동안 그 광고가 게재되지 않는다. 그 사실을 사용자에게 함께 말한다. 안 준 칸은 지금 값 그대로 둔다. 🔴 Google 광고는 2단이다. 먼저 confirm_token 없이 부르면 지금 걸려 있는 제목·설명 전문(current)과 바뀔 값(next)이 온다. Google 소재의 문구는 조회 도구로 볼 수 없어서, 「지금 뭐라고 적혀 있나」를 묻는 자리도 여기다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"ad_id":{"type":"string","description":"소재 번호. list_creatives 로 받은 것"},"title":{"type":"string","description":"바꿀 제목. Google 광고에서는 제목이 여럿이라 이 값이 **첫 줄만** 바꾸고 나머지 줄은 지금 값 그대로 둔다. 오타 한 곳을 고칠 때 쓴다"},"body":{"type":"string","description":"바꿀 설명. Google 광고에서는 설명이 여럿이라 이 값이 **첫 줄만** 바꾼다"},"target_url":{"type":"string","description":"바꿀 주소"},"headlines":{"type":"array","items":{"type":"string"},"description":"Google 광고 전용. 제목 전체를 통째로 바꿀 때. 🔴 준 것이 지금 것을 **대신한다.** 지우면 안 될 줄까지 함께 적어야 한다. 3개 이상, 각 30자까지. 한 줄만 고치실 때는 title 을 쓴다"},"descriptions":{"type":"array","items":{"type":"string"},"description":"Google 광고 전용. 설명 전체를 통째로 바꿀 때. 🔴 준 것이 지금 것을 대신한다. 2개 이상, 각 90자까지. 한 줄만 고치실 때는 body 를 쓴다"},"image_url":{"type":"string","description":"OpenAI 광고 전용. 바꿔 달 이미지의 공개 주소. 올리지 못하면 문구까지 함께 멈춘다. 한 변 1200화소까지이고 정사각형을 권한다"},"confirm_token":{"type":"string","description":"2단 확인표. 처음에는 비워 둔다. 그러면 바뀔 내용만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다"}},"required":["workspace_owner","ad_id"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_keywords":{"post":{"operationId":"list_keywords","summary":"키워드와 그 성과를 함께 조회한다. 일치 유형·상태·키워드별 입찰가·품질평가점수와 노출·클릭·비용·전환이 한 번에 온다. 날짜로 쪼개지지 않고 키워드 단위로 합산해서 오며, 비율은 합산값에서 다시 계산한 것이다. ⚠","description":"키워드와 그 성과를 함께 조회한다. 일치 유형·상태·키워드별 입찰가·품질평가점수와 노출·클릭·비용·전환이 한 번에 온다. 날짜로 쪼개지지 않고 키워드 단위로 합산해서 오며, 비율은 합산값에서 다시 계산한 것이다. ⚠️ 제외 키워드는 이 목록에 없다. 게재를 만드는 키워드만 담는 뷰이기 때문이다. 🔴 Google 광고에만 있다. OpenAI 광고에는 키워드가 없고 그 자리를 맥락 힌트가 맡는다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"ad_group_id":{"type":"string","description":"이 광고그룹만. 안 주면 계정 전체"},"campaign_id":{"type":"string","description":"이 캠페인만. 안 주면 계정 전체"},"days":{"type":"integer","description":"며칠치 (1~31, 기본 7)"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/list_search_terms":{"post":{"operationId":"list_search_terms","summary":"사람이 **실제로 친 검색어**를 조회한다. 키워드 목록과 다르다. 넓은 일치 하나가 엉뚱한 검색을 끌어오고 있어도 키워드 표에는 그 낱말이 안 보인다. 어느 키워드가 그 검색어를 끌어왔는지도 함께 온다. 비용이 큰","description":"사람이 **실제로 친 검색어**를 조회한다. 키워드 목록과 다르다. 넓은 일치 하나가 엉뚱한 검색을 끌어오고 있어도 키워드 표에는 그 낱말이 안 보인다. 어느 키워드가 그 검색어를 끌어왔는지도 함께 온다. 비용이 큰 것부터 실려 오므로 제외할 것을 찾을 때 먼저 본다. status 가 NONE 인 것은 키워드로도 제외로도 등록되지 않은 검색어라는 뜻이고 손댈 여지가 거기에 있다. 🔴 Google 광고에만 있다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"ad_group_id":{"type":"string","description":"이 광고그룹만. 안 주면 계정 전체"},"campaign_id":{"type":"string","description":"이 캠페인만. 안 주면 계정 전체"},"days":{"type":"integer","description":"며칠치 (1~31, 기본 7)"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/generate_keyword_ideas":{"post":{"operationId":"generate_keyword_ideas","summary":"키워드 후보와 월 검색량·경쟁도·입찰가 범위를 받는다. 낱말을 주거나 페이지 주소를 주면 그것을 씨앗으로 아이디어를 낸다. 둘 다 줘도 된다. 🔴 광고를 바꾸지 않으며, 무엇을 넣을지 정하기 전에 보는 자리다. ⚠","description":"키워드 후보와 월 검색량·경쟁도·입찰가 범위를 받는다. 낱말을 주거나 페이지 주소를 주면 그것을 씨앗으로 아이디어를 낸다. 둘 다 줘도 된다. 🔴 광고를 바꾸지 않으며, 무엇을 넣을지 정하기 전에 보는 자리다. ⚠️ Google 이 이 계열 호출에만 따로 분당 한도를 걸어 두었으므로 같은 씨앗으로 되풀이 부르지 않는다. 검색량은 월 평균의 구간값이고, 입찰가 범위는 「첫 화면에 뜨려면 대략 얼마」의 참고치이지 낙찰가가 아니다. 🔴 Google 광고에만 있다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"keywords":{"type":"array","items":{"type":"string"},"description":"씨앗 낱말"},"page_url":{"type":"string","description":"씨앗으로 쓸 페이지 주소"}},"required":["workspace_owner"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/add_keywords":{"post":{"operationId":"add_keywords","summary":"광고그룹에 키워드를 넣는다. 일치 유형은 exact·phrase·broad 이고 기본은 phrase 다. 🔴 **넣은 키워드는 게재 가능 상태로 들어가서**, 광고그룹과 캠페인이 켜져 있으면 그 즉시 노출이 시작된","description":"광고그룹에 키워드를 넣는다. 일치 유형은 exact·phrase·broad 이고 기본은 phrase 다. 🔴 **넣은 키워드는 게재 가능 상태로 들어가서**, 광고그룹과 캠페인이 켜져 있으면 그 즉시 노출이 시작된다. 캠페인·광고그룹·소재가 일시중지로 만들어지는 것과 다르므로 2단 확인을 거치며, 사용자에게 이 사실을 반드시 함께 말한다. 🔴 일치 유형은 넣은 뒤 바꿀 수 없다(Google 이 불변 필드로 둔다). 🔴 지우는 도구는 없다. 한 번에 50개까지이고, 겹치는 키워드가 하나라도 있으면 Google 이 요청 전체를 거절한다. 🔴 Google 광고에만 있다.","tags":["member · 2단 승인"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"ad_group_id":{"type":"string","description":"어느 광고그룹에 넣나"},"keywords":{"type":"array","description":"넣을 키워드. 한 번에 50개까지","items":{"type":"object","properties":{"text":{"type":"string","description":"80자·10낱말 이내"},"match_type":{"type":"string","enum":["exact","phrase","broad"],"description":"기본 phrase"},"bid_krw":{"type":"integer","description":"이 키워드만의 입찰가. 안 주면 광고그룹 값을 쓴다. 🔴 사용자가 말한 금액만 넣는다"}},"required":["text"]}},"confirm_token":{"type":"string","description":"2단 확인표. 처음에는 비워 둔다. 그러면 바뀔 내용만 오고 광고는 안 바뀐다. 그 내용을 사용자에게 보여 주고 답을 받은 뒤에만, 받은 값을 그대로 넣어 다시 부른다"}},"required":["workspace_owner","ad_group_id","keywords"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/agent/tools/add_negative_keywords":{"post":{"operationId":"add_negative_keywords","summary":"제외 키워드를 넣어 그 말로는 광고가 뜨지 않게 한다. 🔴 캠페인에 달면 그 캠페인 전체에서, 광고그룹에 달면 그 그룹에서만 막힌다. 뜻이 다르므로 기본값이 없고 사용자가 고른 대로 넣는다. 「브랜드와 무관한 말」","description":"제외 키워드를 넣어 그 말로는 광고가 뜨지 않게 한다. 🔴 캠페인에 달면 그 캠페인 전체에서, 광고그룹에 달면 그 그룹에서만 막힌다. 뜻이 다르므로 기본값이 없고 사용자가 고른 대로 넣는다. 「브랜드와 무관한 말」은 캠페인에, 「이 그룹에는 안 맞지만 저 그룹에는 맞는 말」은 광고그룹에 단다. 🔴 제외 키워드에는 입찰가가 없다. 이미 쌓인 성과를 되돌리지 않고 앞으로의 노출만 막는다. 무엇을 막을지는 list_search_terms 로 먼저 본다. 🔴 Google 광고에만 있다.","tags":["member"],"security":[{"bearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_owner":{"type":"string","description":"어느 워크스페이스인가. get_me 나 list_workspaces 가 준 owner 값(이메일)을 그대로 쓴다. 필수"},"level":{"type":"string","enum":["campaign","ad_group"],"description":"어디에 다나"},"id":{"type":"string","description":"level 이 가리키는 캠페인 또는 광고그룹 번호"},"keywords":{"type":"array","description":"막을 말. 한 번에 50개까지","items":{"type":"object","properties":{"text":{"type":"string","description":"80자·10낱말 이내"},"match_type":{"type":"string","enum":["exact","phrase","broad"],"description":"기본 phrase"}},"required":["text"]}}},"required":["workspace_owner","level","id","keywords"]}}}},"responses":{"200":{"description":"성공","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"result":{"type":"object","additionalProperties":true},"error":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"토큰이 없거나 만료됨"}}}},"/api/mcp-device":{"post":{"operationId":"device_authorization","summary":"기기 인증 시작 (RFC 8628) — 브라우저 없는 봇의 가입·로그인","tags":["auth"],"security":[],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"client_id":{"type":"string"},"client_name":{"type":"string"}}}}}},"responses":{"200":{"description":"device_code · user_code · verification_uri"}}}},"/api/mcp-token":{"post":{"operationId":"token","summary":"토큰 발급 — authorization_code · refresh_token · device_code","tags":["auth"],"security":[],"responses":{"200":{"description":"access_token · refresh_token"}}}}}}