sayren Docs
상품

상품 등록

POST
/v1/products

Authorization

accessToken
headerAuthorizationBearer <token>

Sayren 계정 토큰(로그인 토큰 또는 개인 액세스 토큰, RFC 9068 JWT)

Header Parameters

X-Store-Id*string

대상 상점 id. 토큰의 상점 범위 밖이면 403 STORE_NOT_GRANTED, 없으면 400 STORE_ID_REQUIRED다

idempotency-key?string

멱등키. 같은 키로 다시 보내면 처음 결과를 돌려주고 한 번만 적용한다. 재시도에는 같은 키를 쓴다

Lengthlength <= 255

Request Body

application/json
  1. body
name*string
Length1 <= length <= 100
categoryId*string
Length1 <= length
salePrice*integer

판매가. 원(KRW) 단위 정수, 최소 10원, 10원 단위

Multiple Of10
Range10 <= value
originalPrice?integer

정가(할인 전 표시 가격). 원 단위. 비교용 표시 값이고 결제 금액은 판매가(즉시할인이 있으면 할인 적용가)다. 스토어프론트가 판매가보다 클 때 취소선·할인율로 보인다. 즉시할인은 PUT /v1/products/{productId}/discount로 따로 정한다

pointEarnRateBp?|

구매 적립률 덮어쓰기(만분율, 100 = 1%, 0~3000, 이슈 #93). null이면 상점 기본 적립률, 0이면 이 상품은 적립하지 않는다. 결제 확정 시점 값이 주문상품에 남는다. 전체 수정(PUT)에서 생략하면 지금 값을 유지한다

Range0 <= value <= 3000
description?string
descriptionJson?string|null
images?array<>

상품 이미지 주소 목록. 첫 장이 대표 이미지(썸네일)다

Items1 <= items <= 10
attributes?array<>
refundPolicy?|

상품별 환불 정책 — 준 항목만 상점 기본을 덮어쓴다. null이나 생략은 상점 기본을 그대로 쓴다는 뜻이다. 반품·교환 배송비(returnDeliveryFee·exchangeDeliveryFee)는 배송 상품에만 줄 수 있다(다른 유형은 400)

optionGroups?array<>
Itemsitems <= 3
Default[]
variants*array<>
Items1 <= items <= 500
addonGroups?array<>

추가 선택 옵션명 전체(이슈 #59). 주면 통째로 바꾸고, 생략하면 등록은 없음·수정은 현재 값을 그대로 둔다. 끄려면 빈 배열을 보낸다. 기능이 열리기 전에는 비어 있지 않은 값이 409 OPTION_ADDONS_UNAVAILABLE이다

Itemsitems <= 5
customInputs?array<>

직접 입력 항목 전체(이슈 #59). 배열 순서가 표시 순서다. 주면 통째로 바꾸고, 생략하면 등록은 없음·수정은 현재 값을 그대로 둔다. 항목명에 개인정보성 단어(CUSTOM_INPUT_FORBIDDEN_WORDS)가 있으면 400 CUSTOM_INPUT_LABEL_FORBIDDEN, 기능이 열리기 전에는 비어 있지 않은 값이 409 OPTION_ADDONS_UNAVAILABLE이다

Itemsitems <= 5
optionSort?string

옵션 값 정렬 순서(이슈 #59). 서버가 이 순서로 값의 sortOrder를 다시 매긴다. 생략하면 등록은 REGISTERED, 수정은 현재 값이다

Value in"REGISTERED""NAME""PRICE_ASC""PRICE_DESC"
sourceOptionSetIds?array<string>

쓰기 전용(이슈 #59) — 이 저장으로 옵션을 불러온 저장 옵션 id. 상품 저장과 같은 트랜잭션에서 불러오기 기록을 남겨 저장 옵션의 importedProductCount를 센다. 없는 id는 무시한다

Itemsitems <= 10
inventoryMode?string

재고 방식(이슈 #118). DATED면 날짜별 달력(PUT /products/{id}/calendar)이 재고·가격이고 주문서 줄은 숙박 기간(stay)을 받는다. 생략하면 등록은 STANDARD, 수정은 지금 값. 판매 이력이 있으면 바꿀 수 없다(409 INVENTORY_MODE_LOCKED)

Value in"STANDARD""DATED"
flowId?|

주문 흐름(이슈 #115) — 게시한 흐름 id. null이면 카테고리의 흐름(없으면 기본 흐름)을 쓴다. 생략하면 등록은 null, 수정은 지금 값. 게시하지 않은 흐름은 409 FLOW_NOT_PUBLISHED. 이미 결제된 주문은 결제 때 붙은 흐름을 그대로 따른다

fulfillment?|

상품 이행. type이 유형이고 같은 이름의 키가 유형별 속성이다. 생략하면 배송 상품(기본값)이다. 배송 상품이 아닌 유형은 판매가 열린 유형만 등록할 수 있다(409 FULFILLMENT_TYPE_NOT_AVAILABLE)

Response Body

성공

application/json
  1. response
meta*
data*
error*|null
curl -X POST 'https://api.sayren.io/v1/products' \  -H 'X-Store-Id: string' \  -H 'Content-Type: application/json' \  -d '{  "name": "오버핏 코튼 반팔 티셔츠",  "categoryId": "cat_tshirt",  "salePrice": 29000,  "originalPrice": 39000,  "description": "<p>도톰한 20수 코튼으로 만든 오버핏 반팔 티셔츠입니다.</p>",  "images": [    "https://cdn.avarlabs.com/demo/tshirt-white.jpg"  ],  "fulfillment": {    "type": "SHIPPING",    "shipping": {      "deliveryType": "CONDITIONAL_FREE",      "deliveryFee": 3000,      "conditionalFreeAmount": 50000    }  },  "refundPolicy": {    "returnDeliveryFee": 3000,    "exchangeDeliveryFee": 6000  },  "optionGroups": [    {      "name": "색상",      "values": [        {          "name": "화이트"        },        {          "name": "블랙"        }      ]    },    {      "name": "사이즈",      "values": [        {          "name": "M"        },        {          "name": "L"        }      ]    }  ],  "variants": [    {      "valueNames": [        "화이트",        "M"      ],      "stockQuantity": 50    },    {      "valueNames": [        "화이트",        "L"      ],      "stockQuantity": 40    },    {      "valueNames": [        "블랙",        "M"      ],      "stockQuantity": 35    },    {      "valueNames": [        "블랙",        "L"      ],      "additionalPrice": 1000,      "stockQuantity": 20    }  ]}'
{  "meta": {    "status": 201,    "code": "OK",    "message": "OK",    "isSuccess": true  },  "data": {    "productId": "prod_3f9a1c2b7d4e",    "productNo": 482,    "name": "오버핏 코튼 반팔 티셔츠",    "status": "SALE",    "salePrice": 29000,    "discountedPrice": null,    "stockQuantity": 145,    "categoryId": "cat_tshirt",    "thumbnailUrl": "https://cdn.avarlabs.com/demo/tshirt-white.jpg",    "hasOptions": true,    "updatedAt": "2026-09-24T10:30:00+09:00",    "createdAt": "2026-09-24T10:30:00+09:00",    "description": "<p>도톰한 20수 코튼으로 만든 오버핏 반팔 티셔츠입니다.</p>",    "descriptionJson": null,    "originalPrice": 39000,    "images": [      "https://cdn.avarlabs.com/demo/tshirt-white.jpg"    ],    "attributes": [],    "optionGroups": [      {        "groupId": "og_color",        "name": "색상",        "sortOrder": 0,        "values": [          {            "valueId": "ov_white",            "name": "화이트",            "sortOrder": 0          },          {            "valueId": "ov_black",            "name": "블랙",            "sortOrder": 1          }        ]      },      {        "groupId": "og_size",        "name": "사이즈",        "sortOrder": 1,        "values": [          {            "valueId": "ov_m",            "name": "M",            "sortOrder": 0          },          {            "valueId": "ov_l",            "name": "L",            "sortOrder": 1          }        ]      }    ],    "variants": [      {        "variantId": "var_white_m",        "variantNo": "482-01",        "valueIds": [          "ov_white",          "ov_m"        ],        "name": "화이트 / M",        "additionalPrice": 0,        "stockQuantity": 50,        "sku": null,        "barcode": null,        "costPrice": null,        "weightGram": null,        "sellerCode": null,        "usable": true      },      {        "variantId": "var_white_l",        "variantNo": "482-02",        "valueIds": [          "ov_white",          "ov_l"        ],        "name": "화이트 / L",        "additionalPrice": 0,        "stockQuantity": 40,        "sku": null,        "barcode": null,        "costPrice": null,        "weightGram": null,        "sellerCode": null,        "usable": true      },      {        "variantId": "var_black_m",        "variantNo": "482-03",        "valueIds": [          "ov_black",          "ov_m"        ],        "name": "블랙 / M",        "additionalPrice": 0,        "stockQuantity": 35,        "sku": null,        "barcode": null,        "costPrice": null,        "weightGram": null,        "sellerCode": null,        "usable": true      },      {        "variantId": "var_black_l",        "variantNo": "482-04",        "valueIds": [          "ov_black",          "ov_l"        ],        "name": "블랙 / L",        "additionalPrice": 1000,        "stockQuantity": 20,        "sku": null,        "barcode": null,        "costPrice": null,        "weightGram": null,        "sellerCode": null,        "usable": true      }    ],    "addonGroups": [      {        "groupId": "og_wrap",        "name": "선물 포장",        "sortOrder": 1,        "required": false,        "values": [          {            "valueId": "ov_wrap_box",            "name": "상자 포장",            "sortOrder": 1,            "additionalPrice": 2000,            "usable": true          }        ]      }    ],    "customInputs": [      {        "inputId": "cin_engrave",        "label": "각인 문구",        "placeholder": "영문 10자까지",        "maxLength": 10,        "required": false,        "usable": true,        "sortOrder": 1      }    ],    "optionSort": "REGISTERED",    "fulfillment": {      "type": "SHIPPING",      "shipping": {        "deliveryType": "CONDITIONAL_FREE",        "deliveryFee": 3000,        "conditionalFreeAmount": 50000,        "shippingAddressId": "adr_ship_main",        "returnAddressId": "adr_return_main"      }    },    "fulfillmentTypeLocked": true,    "refundPolicy": {      "returnDeliveryFee": 3000,      "exchangeDeliveryFee": 6000    },    "discount": null,    "sample": false  },  "error": null}