Rooroo ShopBuilder 공개 API v1
베이스 URL: https://builder.iodev.kr/api/v1 · 모든 응답은 JSON, UTF-8. 모든 요청은 토큰이 속한 사이트(쇼핑몰) 로 자동 스코프됩니다. 다른 테넌트/사이트의 데이터에는 접근할 수 없습니다.
1. 인증
| 방식 | 헤더 | 발급처 | 용도 |
|---|---|---|---|
| API 키 | X-API-Key: rk_live_… (또는 Authorization: Bearer rk_live_…) | 관리자 콘솔 > 앱 마켓 > API 키 | 테넌트 자체 연동, MCP, 스크립트 |
| OAuth2 액세스 토큰 | Authorization: Bearer rat_… | /api/apps/oauth/token | 마켓 앱(설치별), 프라이빗 앱 |
1.1 OAuth2 (앱)
- client_credentials (프라이빗 앱 / 설치 클라이언트):
POST /api/apps/oauth/tokenwithgrant_type=client_credentials&client_id&client_secret[&scope]→{ access_token, token_type:"Bearer", expires_in:3600, scope } - authorization_code (마켓 앱이 다른 쇼핑몰의 동의를 받을 때):
- 사용자를
GET /api/apps/oauth/authorize?client_id&redirect_uri&scope=products:read orders:read&state&response_type=code로 보냄 → 관리자 로그인 → 동의 화면 redirect_uri?code=rac_…&state=…로 복귀 (거부 시error=access_denied)POST /api/apps/oauth/tokengrant_type=authorization_code&code&client_id&client_secret&redirect_uri→{ access_token, refresh_token, expires_in }
- refresh_token:
grant_type=refresh_token&refresh_token&client_id&client_secret(리프레시 토큰 유효 90일, 1회 사용) - 본문은
application/x-www-form-urlencoded또는 JSON, HTTP Basic(client_id:client_secret) 도 허용. - 마켓 앱이 설치될 때 설치별 클라이언트와 1년짜리 액세스 토큰이 자동 발급되어
app.installed웹훅의credentials로 전달됩니다 (APPS.md 참고).
1.2 스코프
| 스코프 | 허용 범위 |
|---|---|
products:read / products:write | 상품 조회 / 생성·수정·삭제·매장별 가격재고 |
categories:read / categories:write | 카테고리 |
orders:read / orders:write | 주문 조회 / 상태 변경 |
members:read / members:write | 회원 조회 / 등급·상태 수정 |
stores:read | 매장, 사이트 테마/설정 |
pages:read / pages:write | 빌더 페이지 조회 / 초안 저장·발행 |
webhooks:write | 웹훅 구독 CRUD |
analytics:read | 구매 분석 개요 |
:write 는 같은 리소스의 :read 를 포함합니다.
1.3 레이트리밋
토큰/키당 분당 600 요청 (플랫폼 설정으로 조정). 응답 헤더 X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. 초과 시 429 + error.code = rate_limited, retry_after(초).
2. 응답 형식
{ "ok": true, "data": { … }, "meta": { "page": 1, "limit": 20, "total": 1573 } }
{ "ok": false, "error": { "code": "not_found", "message": "상품을 찾을 수 없습니다" } }
에러 코드: unauthorized(401) invalid_token token_expired invalid_api_key insufficient_scope(403) app_disabled(403) not_found(404) bad_request(400) rate_limited(429) error(400/500).
목록 엔드포인트는 ?page=1&limit=20 (최대 100) 페이지네이션을 사용합니다. 모든 쓰기 요청은 테넌트 감사 로그(audit_logs)에 기록됩니다.
3. 엔드포인트
3.1 공통
| 메서드 | 경로 | 스코프 | 설명 |
|---|---|---|---|
| GET | /me | (없음) | 토큰 정보, 스코프, 사이트/테넌트 |
| GET | /site | stores:read | 사이트 이름/테마/설정 |
| GET | /stores | stores:read | 매장 목록 (PG 설정 제외) |
3.2 상품
| 메서드 | 경로 | 스코프 | 설명 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| GET | `/products?q&category_id&status=all | active | hidden | soldout | draft&store_id&sort=best | new | name | price_asc | price_desc&page&limit` | products:read | 목록. store_id 를 주면 해당 매장 가격/재고 기준 공개 카탈로그 |
| GET | /products/{id}?store_id | products:read | 상세 (stores[] 매장별 가격/재고 포함) | ||||||||
| POST | /products | products:write | 생성. body: name*, slug, category_id, barcode, brand, spec, unit, origin, summary, description(HTML), images[], thumbnail_url, base_price, tax_free, min_qty, max_qty, tags[], badges[], status, info_notice{}, stores[] | ||||||||
| PATCH | /products/{id} | products:write | 부분 수정 (위 필드 + stores[]) | ||||||||
| DELETE | /products/{id} | products:write | 삭제 | ||||||||
| PUT | /products/{id}/stores | products:write | 매장별 가격/재고: `{ "stores":[{ "store_id":1, "price":3900, "sale_price":2900, "stock":120, "stock_mode":"manual | pos | unlimited", "is_active":1 }] }` |
예시:
curl -X POST https://builder.iodev.kr/api/v1/products -H "X-API-Key: rk_live_…" -H "Content-Type: application/json" \
-d '{"name":"유기농 바나나 1kg","base_price":4900,"category_id":12,"tags":["신선","과일"],"stores":[{"store_id":1,"price":4900,"stock":30,"stock_mode":"manual"}]}'
3.3 카테고리
| 메서드 | 경로 | 스코프 |
|---|---|---|
| GET | /categories (트리) | categories:read |
| GET | /categories/{id} | categories:read |
| POST | /categories { name*, slug, parent_id, image_url, icon, sort_order, is_visible } | categories:write |
| PATCH | /categories/{id} | categories:write |
| DELETE | /categories/{id} (소속 상품은 미분류로) | categories:write |
3.4 주문
| 메서드 | 경로 | 스코프 | 설명 |
|---|---|---|---|
| GET | /orders?status&store_id&from&to&q&member_id&page&limit | orders:read | 목록 |
| GET | /orders/{id} | orders:read | 상세: items[], events[], delivery{}, payment{provider,method,status,amount} |
| PATCH | /orders/{id}/status { status*, reason } | orders:write | 상태 전이: pending→paid, paid→preparing→shipping→delivered→confirmed, paid/preparing→cancelled, … 허용되지 않는 전이는 400 |
주문 상태: pending 결제대기 · paid 결제완료 · preparing 상품준비 · shipping 배송중 · delivered 배송완료 · confirmed 구매확정 · cancel_requested 취소요청 · cancelled 취소 · refunded 환불 · failed 결제실패
3.5 회원
| 메서드 | 경로 | 스코프 | |
|---|---|---|---|
| GET | /members?q&grade&status&page&limit | members:read | |
| GET | /members/{id} (주소, 주문 건수/금액 포함) | members:read | |
| PATCH | /members/{id} `{ name, grade, default_store_id, status: active | blocked }` | members:write |
비밀번호/인증 정보는 노출·수정되지 않습니다. 탈퇴는 API 로 할 수 없습니다(법정 보존 분리 절차).
3.6 페이지 (빌더)
| 메서드 | 경로 | 스코프 | 설명 |
|---|---|---|---|
| GET | /pages | pages:read | 목록 |
| GET | /pages/{id} | pages:read | draft_data / published_data (Puck Data) |
| PATCH | /pages/{id} { data, title, path, seo } | pages:write | 초안 저장(버전 기록) |
| POST | /pages/{id}/publish | pages:write | 발행 → page.published 웹훅 |
Puck Data 형식: { "root": { "props": { "title": "홈" } }, "content": [ { "type": "Hero", "props": { "id": "Hero-1", "title": "…" } } ], "zones": {} }. 사용 가능한 블록 타입과 props 는 에디터의 블록 카탈로그(src/lib/builder/blocks.ts)와 동일하며, 마켓 블록은 AppBlock 타입입니다.
3.7 웹훅 구독
| 메서드 | 경로 | 스코프 | |
|---|---|---|---|
| GET | /webhooks | webhooks:write | |
| POST | /webhooks { url, events:[…], name } → { id, secret } (secret 은 1회 표시) | webhooks:write | |
| GET / PATCH / DELETE | /webhooks/{id} (`{ url, events, name, status: active | paused }`) | webhooks:write |
| POST | /webhooks/{id}/test | webhooks:write |
앱 토큰은 자기 설치의 구독만, API 키는 테넌트 구독만 다룹니다. 이벤트/서명 검증은 APPS.md §4.
3.8 분석
| 메서드 | 경로 | 스코프 | 설명 |
|---|---|---|---|
| GET | /analytics/overview | analytics:read | RFM 세그먼트 분포, KPI(회원/구매자/재구매율/이탈위험), 카테고리·요일·시간대 매출, 인기상품, 매장별 선호 (분석 모듈 실행 결과 기반) |
4. MCP 서버
엔드포인트 POST https://builder.iodev.kr/api/mcp — Streamable HTTP, JSON-RPC 2.0, 프로토콜 2025-03-26(2024-11-05 / 2025-06-18 도 수락). 인증은 REST 와 동일(API 키 또는 Bearer). 도구별 스코프가 없으면 tools/list 에서 숨겨집니다.
| 도구 | 스코프 | 설명 |
|---|---|---|
list_products / get_product / update_product | products:read/write | 상품 검색·상세·수정(매장별 가격/재고 포함) |
list_orders / get_order / update_order_status | orders:read/write | 주문 조회·상태 변경 |
list_members | members:read | 회원 검색 |
list_pages / get_page / update_page_draft / publish_page | pages:read/write | 빌더 페이지 |
site_summary | stores:read | 사이트 요약(건수·매출·테마) |
run_analytics_overview | analytics:read | 구매 분석 개요 |
클라이언트 등록:
# Claude Code
claude mcp add --transport http rooroo https://builder.iodev.kr/api/mcp --header "Authorization: Bearer rk_live_…"
// Cursor (.cursor/mcp.json) / Claude Desktop (mcpServers)
{ "mcpServers": { "rooroo": { "url": "https://builder.iodev.kr/api/mcp", "headers": { "Authorization": "Bearer rk_live_…" } } } }
curl 로 직접 호출:
curl -s https://builder.iodev.kr/api/mcp -H "Authorization: Bearer rk_live_…" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_products","arguments":{"q":"바나나","limit":5}}}'
5. 변경 이력
- v1 (2026-11): 최초 공개. 하위 호환이 깨지는 변경은
/api/v2로 분리합니다.