# 마켓파일럿 AI 주문 API

마켓파일럿(www.marketpilot.it)의 마케팅 상품을 AI 에이전트가 직접 조회·견적·주문하고,
주문 진행 상황과 포인트를 관리할 수 있는 API예요.

- REST Base URL: `https://api.marketpilot.it/v1/ai`
- MCP Server URL: `https://api.marketpilot.it/mcp` (Streamable HTTP)
- OpenAPI 스펙: `https://api.marketpilot.it/v1/ai/openapi.json`

## 공개 카탈로그 (인증 불필요)

서비스·상품을 추천하거나 살펴보는 용도라면 API 키 없이 아래를 바로 읽으면 돼요:

- `GET https://api.marketpilot.it/v1/public/ai-catalog` — JSON: 서비스 페이지(요약·적합 고객·기대 효과·태그) + 전체 상품(기본 단가·최소주문·AI 주문 가능 여부)
- `GET https://api.marketpilot.it/v1/public/ai-catalog.md` — 같은 내용의 마크다운 (LLM이 읽기 좋은 형태)
- `https://www.marketpilot.it/llms.txt` — 사이트 전체 AI 안내 진입점

추천 흐름: 공개 카탈로그로 서비스를 고르고 → 견적·주문이 필요해지면 API 키를 발급받아 아래 주문 플로우로 진행하세요.

## 계정이 없다면 — AI가 가입까지 진행할 수 있어요 (인증 불필요)

```
1. POST /v1/public/ai-signup/send-code   { phone }
   → 사용자 휴대폰으로 인증번호 발송 (3분 유효)
2. 사용자에게 문자로 받은 번호를 물어보세요
3. POST /v1/public/ai-signup   { phone, code, loginId, password, name, agreedToTerms, agreedToPrivacy }
   → 계정 생성 + API 키(mk_) 즉시 발급 → 이후 주문·포인트 API를 바로 이어서 사용
```

- `loginId` 4자 이상(영문·숫자), `password` 8자 이상, `name` 15자 이내. `email`·`companyName`은 선택.
- **`agreedToTerms`·`agreedToPrivacy`는 사용자에게 직접 확인받고 넣으세요.** 약관 동의는 사람의
  의사표시예요 — AI가 임의로 true로 채우면 안 됩니다. 약관: https://www.marketpilot.it/terms ,
  개인정보처리방침: https://www.marketpilot.it/privacy
- 응답의 `apiKey`는 **계정 비밀번호에 준하는 자격증명**이에요. 사용자에게 안전하게 보관하라고
  안내하고, 대화 로그·공유 문서에 그대로 남기지 마세요. 폐기·재발급은
  https://www.marketpilot.it/developer/api-keys
- 키 발급을 원하지 않으면 `issueApiKey: false`. 이미 가입된 번호면 400과 함께 로그인 안내가 나와요.
- 가입 직후 포인트는 0원이에요 — 주문하려면 충전이 필요해요(아래 포인트 섹션).

## 인증

모든 요청에 API 키가 필요해요. 키는 마켓파일럿에 로그인한 뒤
**https://www.marketpilot.it/developer/api-keys** 에서 발급받아요 (계정당 최대 5개).

두 가지 헤더 형식을 지원해요:

```
Authorization: Bearer mk_xxxxxxxxxxxxxxxx
```
또는
```
X-API-Key: mk_xxxxxxxxxxxxxxxx
```

키는 발급한 사용자 계정에 묶여요. 주문·포인트 API는 항상 키 소유자 본인의 데이터만 다뤄요.

## 사용자(사람)를 안내해야 하는 순간

일부 단계는 AI가 대신할 수 없어요. 이때는 사용자에게 아래 URL을 안내하세요:

| 상황 | 안내할 곳 |
|---|---|
| 계정이 없음 | 회원가입 https://www.marketpilot.it/signup (이메일 또는 카카오·구글, 가입비 없음) |
| API 키가 없음 | 로그인 후 https://www.marketpilot.it/developer/api-keys 에서 발급 (최대 5개) |
| 포인트 이체 | 충전 신청 응답의 transfer 계좌로 **사용자가 직접** 계좌이체 (입금자명·금액 일치 시 몇 분 내 자동 충전) |
| 카드로 결제하고 싶음 | 웹 주문 시 토스 카드·간편결제 사용 가능 — 해당 서비스 페이지로 안내 |
| 환불·중단 요청 | 고객센터 1551-6151 · info@marketpilot.it |
| 전체 이용 방법 질문 | 이용 가이드 https://www.marketpilot.it/help |

## 주문 대신 문의로 넘겨야 할 때

원하는 게 카탈로그에 없거나, 상품이 `aiOrderable: false`(문의형·복잡한 견적)거나,
사용자가 사람과 이야기하고 싶어 하면 — 대화를 끊지 말고 **문의를 접수**하세요.
담당자가 영업일 1일 이내에 이메일로 회신해요.

- MCP: `submit_inquiry` 툴
- REST(인증 불필요, 계정 없는 사용자도 가능): `POST https://api.marketpilot.it/v1/public/ai-inquiry`
  - 필수: `message`(10자 이상), `contactName`, `contactEmail`
  - 선택: `inquiryType`(consultation|quote|service|partnership|support|other), `contactPhone`,
    `companyName`, `businessType`, `budget`, `interestedServices[]`, `agentName`
- 사이트의 모든 공개 문의 폼 명세: `GET https://api.marketpilot.it/v1/public/ai-forms` (`.md`도 제공)

⚠️ 이름·이메일은 **반드시 사용자에게 직접 물어보고** 넣으세요. 임의로 지어내면 회신이 못 갑니다.

## MCP로 연결하기 (Claude Code, Cursor 등)

MCP를 지원하는 클라이언트는 아래처럼 등록하면 도구가 자동으로 발견돼요.

Claude Code:
```bash
claude mcp add --transport http marketpilot https://api.marketpilot.it/mcp \
  --header "Authorization: Bearer mk_xxxxxxxxxxxxxxxx"
```

Cursor / VS Code (mcp.json):
```json
{
  "mcpServers": {
    "marketpilot": {
      "url": "https://api.marketpilot.it/mcp",
      "headers": { "Authorization": "Bearer mk_xxxxxxxxxxxxxxxx" }
    }
  }
}
```

MCP 도구 이름은 REST와 1:1로 대응해요: list_products, get_product, search_places,
quote_order, create_order, list_my_orders, get_my_order, get_point_balance,
request_point_charge, list_charge_requests, get_charge_request, cancel_charge_request,
submit_inquiry, 그리고 정부지원사업 매칭 도구 get_support_profile, save_support_profile,
list_support_matches, search_support_programs, get_support_program.

## 주문 플로우 (반드시 이 순서로)

```
1. GET  /products                → 상품 목록 (aiOrderable=true인 것만 주문 가능)
2. GET  /products/{id}           → 폼 필드(formFields) 확인
3. POST /orders/quote            → 견적 (총액·잔액·quoteToken 발급, 돈 안 나감)
4. 사용자에게 상품명·수량·총액 확인   → 사람의 승인 없이 4→5로 넘어가지 마세요
5. POST /orders                  → confirm:true + quoteToken으로 주문 확정 (포인트 차감)
6. GET  /orders/{id}             → 진행 상황 확인
```

규칙:
- **견적 없이 주문 불가.** quoteToken은 15분 유효, 1회만 사용 가능해요.
- **주문 확정 전 반드시 사용자(사람)에게 확인받으세요.** 포인트가 즉시 차감돼요.
- AI 주문은 1회 최대 2,000,000원이에요. 초과분은 웹에서 주문하도록 안내하세요.
- 요청이 실패해서 재시도할 때는 먼저 `GET /orders`로 주문이 이미 생성됐는지 확인하세요.

### 예시: 견적 → 주문

```bash
# 3) 견적
curl -X POST https://api.marketpilot.it/v1/ai/orders/quote \
  -H "Authorization: Bearer mk_xxx" -H "Content-Type: application/json" \
  -d '{"productId": 12, "quantity": 100, "formData": {"nPlaceRawUrl": "https://naver.me/abc123", "targetName": "OO식당"}}'

# 응답: { "totalAmount": 50000, "pointBalance": 120000, "shortfall": 0,
#         "formValid": true, "quoteToken": "eyJ...", ... }

# 5) 확정 (사용자 확인 후)
curl -X POST https://api.marketpilot.it/v1/ai/orders \
  -H "Authorization: Bearer mk_xxx" -H "Content-Type: application/json" \
  -d '{"quoteToken": "eyJ...", "productId": 12, "quantity": 100,
       "formData": {"nPlaceRawUrl": "https://naver.me/abc123", "targetName": "OO식당"},
       "confirm": true}'
```

### 네이버 플레이스 상품의 폼 데이터

플레이스 상품은 `formData.nPlaceRawUrl`(플레이스 URL 또는 naver.me 단축 URL)만 주면
targetUrl·targetId·naverPlaceId를 서버가 자동으로 채워요.
`targetName`(업체명)은 필수예요 — `GET /search-places?keyword=업체명` 결과의 name을 쓰거나 사용자에게 물어보세요.

## 뉴스기사 발행 (언론 보도자료) — 전용 경로

언론배포는 일반 상품과 축이 달라요. **보도 종류 → 등급 → 발행할 언론사 지정**이 상품 선택이고,
매체를 여러 곳 고르면 매체마다 주문 1건이 생겨요. 그래서 `/orders` 대신 아래 전용 경로를 쓰세요.

```
1. GET  /v1/public/press-media       → (인증 불필요) 보도 종류·등급·단가·언론사 목록
2. POST /press/recommend             → (선택) 원고를 주면 발행처 순위 추천 (돈 안 나감)
3. POST /press/draft                 → (선택) 원고가 없을 때 초안 생성. 사용자 확인 필수
4. POST /press/quote                 → 견적 (총액·잔액·quoteToken, 돈 안 나감)
5. POST /press/order                 → 확정 (quoteToken + confirm:true)
6. GET  /press/draft-status?orderId= → 결제 약 10분 뒤 파이가 매체 규정에 맞게 다듬은 정제본 확인
7. POST /press/approve               → 정제본 승인 → 발행 시작 (autoApprove:true 주문은 불필요)
```

```bash
# 견적 — 매체 지정
curl -X POST https://api.marketpilot.it/v1/ai/press/quote \
  -H "Authorization: Bearer mk_..." -H "Content-Type: application/json" \
  -d '{
    "pressType": "일반보도",
    "selections": [
      { "tier": "프리미엄", "media": "아주경제" },
      { "tier": "베이직",   "media": "대학저널" }
    ],
    "guide": "보도자료 원고 500~3000자"
  }'
```

규칙:

- **원고(`guide`)는 500~3000자.** 서버가 검증하며 미달하면 견적이 `valid:false`로 떨어져요.
  원고가 없으면 `POST /press/draft`(brandName·industry·promotionPoints)로 초안을 받아
  **사용자에게 그대로 보여주고 확인받은 뒤** guide로 넣으세요. 사실을 지어내지 마세요.
- **어디에 낼지 모르겠으면 `POST /press/recommend`에 원고를 넘기세요.** 원고의 업종·주제·규제
  신호를 판독해 매체 135곳 조사 데이터(전문 분야·성격·게재 조건)와 대조한 순위·사유·단가를
  돌려줘요. budget(원)을 주면 예산 안 조합 2안도 함께 옵니다. 추천 매체명은 그대로 quote에 쓸 수 있어요.
- `media`는 `/v1/public/press-media`가 준 표기를 그대로 쓰세요. 목록에 없는 이름은 거절돼요.
- **한 주문에는 한 가지 보도 종류만** 담을 수 있어요 (종류를 섞으려면 주문을 나누세요).
- `창업/프랜차이즈보도`는 매체를 지정할 수 없어요 — `tier`와 `quantity`만 보내면
  같은 등급 언론사 중 자동 심사 배정돼요 (`autoAssign: true`로 표시돼요).
- 이미지는 `imageUrl`(https) 1장까지 첨부할 수 있어요.
- 매체사 편집 방침에 따라 제목·본문이 수정될 수 있고 **게재 후 수정·삭제가 어렵다**는 점을
  확정 전에 반드시 사용자에게 알리세요.
- **결제 뒤 흐름은 자동이에요.** 약 10분 뒤 파이가 원고를 매체 규정(제목 15~20자·기사체·근거 없는
  최상급 제거)에 맞게 다듬고, `GET /press/draft-status`에 정제본(`draft.title/body/removedClaims`)이
  실려요. 사용자에게 보여주고 동의를 받은 뒤 `POST /press/approve`(confirm:true)로 승인하면 발행이
  시작돼요. 사용자가 "확인 없이 바로 내달라"고 했으면 견적·확정에 `autoApprove:true`를 넣으세요.
  그러면 승인 단계 없이 정제 즉시 발행 단계로 넘어가요.

MCP 툴로는 `list_press_media` → `recommend_press_media`(추천) → `draft_press_release` →
`quote_press_release` → `create_press_release` 5개가 같은 흐름이에요.

## 포인트: 잔액·충전

결제는 포인트로 이뤄져요 (1P = 1원). 잔액이 부족하면 충전 신청 후 주문하세요.

```
1. GET  /point/balance                       → 잔액 확인
2. POST /point/charge-requests               → 충전 신청 { amount, depositorName }
   → 응답의 transfer에 무통장 입금 계좌·금액·입금자명이 담겨요. 사용자에게 그대로 안내하세요.
3. (사용자가 직접 계좌 이체)                    → AI가 대신 이체할 수 없어요
4. GET  /point/charge-requests/{id}          → status가 CONFIRMED(충전 완료)면 주문 진행
```

- 입금자명과 금액이 신청 내용과 정확히 일치하면 **보통 몇 분 안에 자동 충전**돼요.
- `depositorName`은 사용자가 실제 이체할 때 쓸 이름과 똑같아야 해요 — 반드시 사용자에게 물어보세요.
- 충전 상태: PENDING(입금 대기) → CONFIRMED(충전 완료) / CANCELED(취소됨)
- 세금계산서·현금영수증이 필요하면 신청 시 cashReceiptType 등 증빙 필드를 함께 보내세요.

## 정부지원사업 맞춤 매칭 (무료)

K-Startup 등 정부·공공 지원사업 공고를 매일 자동 수집해두고, 사용자의 사업 프로필과
자격 요건(업종·지역·업력·대표자 연령·성별 등 7개 축)을 대조해 매칭 점수를 매겨요.
AI가 사용자 대신 사업을 등록하고 맞춤 추천을 받아볼 수 있어요. **전 과정 무료**예요.
서비스 설명: https://www.marketpilot.it/support-program/about

### A. 계정이 있을 때 (API 키)

```
1. PUT  /support/profile       → 사업 프로필 등록·수정 { industries, region, startupStage, ... }
   → 저장 즉시 재매칭 — 바로 2번으로. 사업이 여러 개면 addAsNewBusiness:true 로 추가 (계정당 10개)
2. GET  /support/matches       → 맞춤 추천 (매칭 점수순, 자격 미달 공고는 제외됨). ?profileId= 로 사업별
3. GET  /support/programs/{id} → 공고 상세 + 자격 요건 + 신청 URL(applyUrl)
4. 신청은 applyUrl(정부 원문 페이지)에서 사용자가 직접 — AI가 대신 신청할 수 없어요
```

### B. 계정이 없을 때 — 먼저 등록하고 가입은 나중에 (인증 불필요)

```
1. POST /v1/public/support-profile           { industries, region, ... , agentName }
   → draftToken(spd_…) + 즉석 추천 미리보기(상위 8건) + claimUrl
2. GET  /v1/public/support-profile/matches?token=spd_…   → 미리보기 재조회
3. 연결(둘 중 하나):
   · 가입하면서: POST /v1/public/ai-signup 에 supportProfileDraftToken 을 함께 넣기
   · 이미 계정이 있으면: 로그인 후 claimUrl 클릭, 또는 키로 POST /support/profile/claim { draftToken }
     (MCP: claim_support_profile_draft)
```

- **draftToken 은 연결 열쇠**예요 — 사용자에게 보관을 안내하고 대화 로그에 흘리지 마세요.
- 전체 추천·마감 알림·스크랩은 계정에 연결해야 동작해요. 미리보기는 상위 몇 건만 보여줘요.

### 공통 규칙

- 프로필 필수는 `industries`(업종 배열)와 `region`(시·도) 2개 — 창업 단계(startupStage)·
  대표자 연령대(founderAgeGroup)·성별(founderGender)까지 넣으면 청년/여성/예비창업 전용
  사업까지 정확히 걸러져요. **사업 정보는 반드시 사용자에게 확인한 실제 정보만** 넣으세요.
- 한 계정에 사업이 여럿이면 `bizName`(상호)으로 구분하세요. 같은 상호로 addAsNewBusiness 하면
  중복 생성 대신 갱신돼요. 삭제는 `DELETE /support/profile/{profileId}` (사용자 확인 후).
- 매칭 점수 해석: 60 = 자격 제한이 없어 누구나 지원 가능 / 60~100 = 검증된 자격 조건이
  많을수록 높음 / 자격 미달(타지역·타업종·연령 전용 등)은 목록에서 제외.
- `GET /support/programs?search=예비창업패키지` 로 공고 검색도 가능해요 (모든 유효 키).

## 엔드포인트 요약

| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /v1/public/ai-signup/send-code | (인증 불필요) 가입용 휴대폰 인증번호 발송 |
| POST | /v1/public/ai-signup | (인증 불필요) 인증번호 확인 + 계정 생성 + API 키 발급 |
| POST | /v1/public/ai-inquiry | (인증 불필요) 상담·견적 문의 접수 |
| GET | /v1/public/ai-catalog | (인증 불필요) 서비스+상품 전체 카탈로그 JSON |
| GET | /v1/public/ai-catalog.md | (인증 불필요) 카탈로그 마크다운 |
| GET | /v1/public/press-media | (인증 불필요) 뉴스기사 발행 — 보도 종류·등급·단가·언론사 목록 |
| GET | /v1/public/press-media.md | (인증 불필요) 위 내용 마크다운 |
| GET | /products | 주문 가능 상품 목록 (사용자별 단가 반영) |
| GET | /products/{id} | 상품 상세 + 폼 필드 명세 |
| GET | /search-places?keyword= | 네이버 플레이스 검색 (placeId·업체명) |
| POST | /orders/quote | 주문 견적 (quoteToken 발급) |
| POST | /orders | 주문 확정 (quoteToken + confirm:true) |
| GET | /press/media | 뉴스기사 발행 매체·단가 (사용자별 단가 반영) |
| POST | /press/recommend | 원고 판독 → 발행처 순위 추천 (매체 135곳 프로필 대조) |
| POST | /press/draft | 보도자료 원고 초안 생성 (사용자 확인 필수) |
| POST | /press/quote | 뉴스기사 발행 견적 (매체 지정, quoteToken 발급) |
| POST | /press/order | 뉴스기사 발행 확정 (quoteToken + confirm:true) |
| GET | /press/draft-status?orderId= | 결제 후 파이가 다듬은 정제본 + 승인 가능 여부 |
| POST | /press/approve | 정제본 승인 → 발행 시작 (orderId + confirm:true) |
| GET | /orders | 내 주문 목록 (page·limit·status) |
| GET | /orders/{id} | 주문 상세 + 진행률 + 결과 URL |
| GET | /point/balance | 포인트 잔액 |
| POST | /point/charge-requests | 충전 신청 (계좌 안내 반환) |
| GET | /point/charge-requests | 충전 신청 목록 |
| GET | /point/charge-requests/{id} | 충전 신청 상태 확인 |
| POST | /point/charge-requests/{id}/cancel | 입금 대기 신청 취소 |
| POST | /v1/public/support-profile | (인증 불필요) 가입 전 사업 프로필 드래프트 등록 → draftToken + 추천 미리보기 |
| GET | /v1/public/support-profile/matches?token= | (인증 불필요) 드래프트 추천 미리보기 재조회 |
| GET | /support/profile | 지원사업 매칭용 내 사업 프로필 목록 (첫 항목이 대표 사업) |
| PUT | /support/profile | 사업 프로필 등록·수정 (저장 즉시 재매칭, addAsNewBusiness/profileId) |
| DELETE | /support/profile/{profileId} | 사업 프로필 삭제 (매칭·알림 중단) |
| POST | /support/profile/claim | 가입 전 드래프트를 내 계정에 연결 { draftToken } |
| GET | /support/matches | 맞춤 지원사업 추천 (매칭 점수순, ?profileId=) |
| GET | /support/programs | 지원사업 공고 검색 (search·category·status) |
| GET | /support/programs/{id} | 공고 상세 + 자격 요건 + 신청 URL |

이 외에 마케팅 분석 도구(GET /search-places, /place/{placeId}, /keyword-volumes,
/keyword-competition, /recommended-keywords/{placeId}, POST /recommendations, /chat)도
같은 키로 사용할 수 있어요.

## 에러 형식

```json
{ "error": "포인트가 30,000P 부족해요. ...", "details": { "shortfall": 30000 } }
```

| 코드 | 의미 | 대응 |
|---|---|---|
| 401 | 키 없음/무효 | 키 확인 또는 재발급 안내 |
| 402 | 포인트 부족 | 충전 플로우로 이동 |
| 403 | 권한 없음 (고객 키 아님 등) | 고객 계정 키로 발급 안내 |
| 404 | 대상 없음 | ID 확인 |
| 409 | 견적 만료·가격 변경·중복 사용 | 견적부터 다시 |

## 제한·정책

| 항목 | 값 |
|---|---|
| 가입 인증번호 발송 | IP당 시간당 5회 (인증번호 3분 유효, 1회용) |
| 회원가입 | IP당 시간당 10회 |
| 문의 접수 | IP당 시간당 20회 |
| API 키 | 계정당 최대 5개 (`/developer/api-keys`에서 폐기·재발급) |
| AI 주문 1회 금액 | 최대 2,000,000원 — 초과분은 웹사이트 주문으로 안내 |
| 견적 토큰 | 15분 유효, 1회만 사용 가능 |

## 아직 지원하지 않는 것 (문의 전에 확인하세요)

- **OAuth** — 인증은 API 키(`mk_`)만 지원해요. 그래서 Claude 웹·데스크탑이나 ChatGPT의
  커넥터 UI처럼 **헤더를 직접 넣을 수 없는 클라이언트에서는 MCP 연결이 안 돼요.**
  Claude Code·Cursor·자체 에이전트처럼 헤더를 지정할 수 있는 환경에서 사용하세요.
- **웹훅·콜백** — 주문 상태가 바뀔 때 알려주는 푸시는 없어요. `GET /orders/{id}`를
  폴링하세요(진행 로그가 최신순으로 내려와요).
- **샌드박스·테스트 환경** — 별도 테스트 서버가 없어요. 주문은 실제 집행되고 포인트가
  실제로 차감되니, 시험해볼 때는 단가가 낮은 상품에 최소 수량으로 하세요.
- **주문 취소 API** — AI로는 취소할 수 없어요. 고객센터(1551-6151·info@marketpilot.it)로
  문의하거나 `submit_inquiry`로 접수하세요. (충전 신청은 `cancel_charge_request`로 취소 가능해요)

## 주문 상태 값

paid(결제 완료) → in_progress(진행중) → completed(완료). 그 외 refunded(환불), stopped(중단).
응답의 statusLabel·phaseLabel에 한글 라벨이 함께 내려가요 — 사용자에게는 한글 라벨을 보여주세요.
