# 표준 API 직접 연동

<figure><img src="https://889768860-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F86EGDbqiEQQc91OjPHgn%2Fuploads%2Ftle9GQksz5g5uj7il8OA%2FAPI%20%E1%84%8B%E1%85%A7%E1%86%AB%E1%84%83%E1%85%A9%E1%86%BC-banner.png?alt=media&#x26;token=38913dae-f1c5-4b5b-bf86-804bac57e7a3" alt=""><figcaption></figcaption></figure>

표준 API 직접 연동은 고객사의 상품 정보를 API를 통해 genser로 데이터를 직접 전송하는 방식입니다.&#x20;

***

genser의 직접 연동 API는 데이터의 확장성과 상호운용성을 위해 다음과 같은 글로벌 기술 표준을 준수합니다.

* **JSON-LD & Schema.org:** 데이터에 의미를 부여하는 구조화된 데이터 포맷을 사용하여, Vertex AI가 상품의 맥락을 완벽하게 이해하도록 돕습니다.
* **CloudEvents:** 모든 상품 정보 변경을 '이벤트'로 취급하여, 시스템 간의 신뢰성 있는 데이터 교환을 보장합니다.

{% stepper %}
{% step %}

## 연동 준비하기 (Prepare)

API를 호출하기 위해 필요한 기본 정보입니다.

* **API Endpoint:** `https://api.genser.app/collectors/products`
* **Method:** `POST`
* **Content-Type:** `application/json` (또는 `application/ld+json`)
* **Service Key:** genser 어드민 \[설정] 메뉴에서 발급받은 `apiKey`

> **데이터 반영 시점 안내**
>
> API로 전송된 데이터는 즉시 검색 결과에 노출되지 않으며, 해당 국가의 현지 시간으로 매일 오전 00:15am에 실행되는 일괄 처리(Batch) 작업을 통해 검색 엔진에 반영됩니다.

{% endstep %}

{% step %}

## 인증하기 (Authenticate)

genser API는 복잡한 토큰 교환 방식 대신, 헤더(Header)에 키 값을 직접 포함하는 간편한 방식을 사용합니다. 어드민에서 발급받은 **Service Key**를 준비해 주세요. (`genser 어드민 > 설정` 에서 확인 가능)

* **Header Name:** `apiKey`&#x20;
* **Value:** 발급받은 키 값 그대로 입력 (Base64 인코딩 불필요)

**HTTP 요청 헤더 예시:**

```
POST /searches/products HTTP/1.1
Host: api.genser.app
Content-Type: application/json
apiKey: cb37cce9d6ae434fa366151b3420a9af //발급 받은 서비스 키
```

{% endstep %}

{% step %}

## 상품 데이터 전송하기 (Send Data)

신규 상품을 등록하거나, 기존 상품 정보(가격, 재고 등)가 변경되었을 때 아래 형식으로 데이터를 전송합니다. **JSON-LD** 및 **CloudEvents** 표준 규격을 따릅니다.

#### 요청 본문 (Request Body)

상품 수집 API를 호출할 때 본문(Body)에 포함해야 하는 최상위 필드입니다. 상세 상품 정보는 `@graph` 객체에 담아 전송합니다.

<table><thead><tr><th width="117.11328125">필드명</th><th width="96.91015625">타입</th><th width="79.609375">구분</th><th>설명</th></tr></thead><tbody><tr><td>@context</td><td>String</td><td>권장</td><td>JSON-LD 데이터의 기준 사전 정의 (값: <code>https://schema.org/</code>)</td></tr><tr><td>specversion</td><td>String</td><td>권장</td><td>CloudEvents 스펙 버전 (값: <code>1.0</code>)</td></tr><tr><td>id</td><td>String</td><td>권장</td><td>요청 건당 고유 식별자 (UUID 등)</td></tr><tr><td>type</td><td>String</td><td>권장</td><td>이벤트 유형 (예: create_product)</td></tr><tr><td>agent</td><td>Object</td><td>필수</td><td>데이터를 전송하는 주체(시스템) 식별값</td></tr><tr><td>@graph</td><td>Object</td><td>필수</td><td>실제 상품 정보가 포함된 Product 객체 리스트</td></tr></tbody></table>

#### 리소스 객체 (Resource Objects)

<table><thead><tr><th width="174.95703125">필드명</th><th width="89.03515625">타입</th><th width="80.3671875">구분</th><th>설명</th></tr></thead><tbody><tr><td>@type</td><td>String</td><td>필수</td><td>객체 타입 정의 (값: <code>Product</code>)</td></tr><tr><td>sku</td><td>String</td><td>필수</td><td>회사 내부에서 상품을 구분할 때 쓰는 관리 코드 (예: A001-Red)</td></tr><tr><td>name</td><td>String</td><td>필수</td><td>고객에게 보여지는 실제 상품의 이름</td></tr><tr><td>category</td><td>Object</td><td>필수</td><td>사이트에 진열되는 카테고리 분류 (예: 의류 > 남성 > 티셔츠)</td></tr><tr><td>└ @type</td><td>String</td><td>필수</td><td>객체 타입 정의 (값: <code>CategoryCode</code>)</td></tr><tr><td>└ name</td><td>String</td><td>필수</td><td>카테고리 명칭 (예: 스니커즈, 아우터)</td></tr><tr><td>└ code</td><td>String</td><td>권장</td><td>카테고리 분류 코드</td></tr><tr><td>brand</td><td>Object</td><td>필수</td><td>이 상품을 만든 브랜드 정보</td></tr><tr><td>└ @type</td><td>String</td><td>선택</td><td>객체 타입 정의 (값: <code>Brand</code>)</td></tr><tr><td>└ id</td><td>String</td><td>필수</td><td>브랜드 아이디</td></tr><tr><td>└ name</td><td>Object</td><td>필수</td><td>브랜드 이름, 브랜드 이름 표기 언어 코드(예: ko)</td></tr><tr><td>description</td><td>Object</td><td>필수</td><td>상품 설명, 언어 코드, 상품 설명 부가 정보 등</td></tr><tr><td>offers</td><td>Object</td><td>필수</td><td>가격 및 재고 정보 객체</td></tr><tr><td>└ @type</td><td>String</td><td>선택</td><td>객체 타입 정의 (값: <code>Offer</code>)</td></tr><tr><td>└ sku</td><td>String</td><td>필수</td><td>판매용 SKU</td></tr><tr><td>└ gtin</td><td>String</td><td>필수</td><td>전 세계적으로 통용되는 상품 고유 번호 (예: 880으로 시작하는 바코드, EAN/UPC)</td></tr><tr><td>└ mpn</td><td>String</td><td>필수</td><td>제조사에서 부여한 부품 번호나 모델명</td></tr><tr><td>└ price</td><td>Number</td><td>필수</td><td>고객이 실제로 결제하게 될 최종 판매 금액</td></tr><tr><td>└ priceCurrency</td><td>String</td><td>필수</td><td>결제 통화 기준 (한국은 KRW, 미국은 USD 등)</td></tr><tr><td>└ availability</td><td>String</td><td>필수</td><td>지금 구매가 가능한지 여부 ( 값: <code>InStock, OutOfStock, PreOrder</code>)</td></tr><tr><td>└ availabilityStarts</td><td>Date</td><td>필수</td><td>상품 판매가 시작되는 날짜와 시간 (2025-11-28T10:00:00Z)</td></tr><tr><td>└ availabilityEnds</td><td>Date</td><td>필수</td><td>상품 판매를 마감하는 날짜와 시간 (2025-11-28T10:00:00Z)</td></tr><tr><td>└ shippingDetails</td><td>Object</td><td>선택</td><td>배송 정보</td></tr><tr><td>└ image</td><td>Object</td><td>필수</td><td>상품 이미지</td></tr><tr><td>additionalProperty</td><td>Array</td><td>선택</td><td>관세청 신고를 위한 HS Code나 친환경 태그 등 특수한 추가 정보</td></tr><tr><td>└ @type</td><td>String</td><td>선택</td><td>정보가 어떤 형태인지 정의 (값: <code>PropertyValue</code>)</td></tr><tr><td>└ propertyID</td><td>String</td><td>선택</td><td><p>정보 이름표 (ID)<br></p><ul><li><code>html</code>: 웹용 HTML 설명</li><li><code>seo_title</code>: 검색 노출용 제목</li><li><code>hsCode</code>: 통관용 관세 코드</li><li><code>sustainabilityTags</code>: 친환경 태그</li></ul></td></tr><tr><td>└ value</td><td>String</td><td>선택</td><td>이름표에 해당하는 실제 내용 (예: 이름표가 <code>hsCode</code>라면, 값은 <code>851762</code>)</td></tr></tbody></table>

<details>

<summary><strong>요청 본문 샘플 코드 예시</strong></summary>

```js
{
  "@context": "https://schema.org/",
  "specversion": "1.0",
  "id": "EVT-CREATE-PRODUCT",
  "type": "create_product",
  "agent": {
    "@type": "Organization",
    "name": "ExampleCorp"
  },
  "@graph": [
    {
      "@type": "Product",
      "sku": "PROD-001-A",
      "name": {
        "@value": "프리미엄 블루투스 이어폰",
        "@language": "ko"
      },
      "description": [
        {
          "@type": "TextObject",
          "text": "완전 무선 블루투스 이어폰으로 고음질 사운드와 편안한 착용감을 제공합니다.",
          "inLanguage": "ko",
          "additionalProperty": [
            {
              "@type": "PropertyValue",
              "propertyID": "html",
              "value": "<p>완전 무선 블루투스 이어폰으로 <strong>고음질 사운드</strong>와 편안한 착용감을 제공합니다.</p>"
            },
            {
              "@type": "PropertyValue",
              "propertyID": "seo_title",
              "value": "프리미엄 블루투스 이어폰 - 고음질 무선 이어폰"
            },
            {
              "@type": "PropertyValue",
              "propertyID": "seo_description",
              "value": {
                "@value": "고음질 완전 무선 이어폰, 장시간 착용에도 편안한 프리미엄 제품",
                "@language": "ko"
              }
            }
          ]
        }
      ],
      "brand": {
        "@type": "Brand",
        "@id": "brand-001",
        "name": {
          "@value": "사운드맥스",
          "@language": "ko"
        },
        "logo": "https://example.com/brand/soundmax-logo.png"
      },
      "category": [
        {
          "@type": "CategoryCode",
          "codeValue": "ELEC001",
          "name": {
            "@value": "전자기기",
            "@language": "ko"
          },
          "position": 1
        },
        {
          "@type": "CategoryCode",
          "codeValue": "AUDIO005",
          "name": {
            "@value": "오디오 기기",
            "@language": "ko"
          },
          "position": 2
        }
      ],
      "positiveNotes": {
        "@value": "고음질, 장시간 배터리, 편안한 착용감",
        "@language": "ko"
      },
      "url": {
        "@value": "https://example.com/product/P001",
        "@language": "ko"
      },
      "itemCondition": "NewCondition",
      "hasAdultConsideration": "UnclassifiedAdultConsideration",
      "countryOfOrigin": {
        "@type": "Country",
        "address": "KR"
      },
      "material": {
        "@value": "플라스틱, 실리콘",
        "@language": "ko"
      },
      "offers": {
        "@type": "Offer",
        "sku": "PROD-001-A",
        "gtin": "8801234567890",
        "mpn": "SM-EAR-2025",
        "price": 129000,
        "priceCurrency": "KRW",
        "priceSpecification": {
          "@type": "UnitPriceSpecification",
          "price": 129000,
          "unitCode": "EA"
        },
        "availability": "InStock",
        "availabilityStarts": "2025-11-28T10:00:00Z",
        "availabliltyEnds": "2026-12-31T23:59:59Z", 
        "inventoryLevel": {
          "@type": "QuantitativeValue",
          "value": 250
        },
        "shippingDetails": {
          "@type": "OfferShippingDetails",
          "weight": {
            "@type": "QuantitativeValue",
            "value": 0.2,
            "unitCode": "KG"
          }
        },
        "image": [
          {
            "@type": "ImageObject",
            "contentUrl": "https://example.com/product/P001/main.jpg",
            "contentSize": "350KB",
            "width": {
              "@type": "QuantitativeValue",
              "value": 1080
            },
            "height": {
              "@type": "QuantitativeValue",
              "value": 1080
            }
          }
        ]
      },
      "additionalProperty": [
        {
          "@type": "PropertyValue",
          "propertyID": "hsCode",
          "value": "851762"
        },
        {
          "@type": "PropertyValue",
          "propertyId": "sustainabilityTags", 
          "value": ["lowEnergyConsumption", "recyclablePackaging"]
        }
      ]
    }
  ]
}
```

</details>

#### 다국어 정보 연동 (Multi-language Support)

단일 요청으로 여러 언어의 상품 정보를 동시에 등록할 수 있습니다. 글로벌 판매를 위해 상품명, 브랜드, 카테고리 등 텍스트 정보에 다국어 값을 설정하려면, 해당 필드를 JSON 배열(`Array`)로 변경하고 언어 코드(`@language`)를 구분하여 입력해 주세요.

* **기본 원칙**
  * **단일 언어:** Object 형식 `{ "@value": "...", "@language": "ko" }`
  * **다국어:** Array 형식 `[ { "ko" 데이터 }, { "en" 데이터 } ]`
* **지원 필드:** `name`, `brand.name`, `category.name`, `positiveNotes`, `material`, `url` 등
* **주의사항:** `description` 필드는 `inLanguage`속성을 사용하여 구분합니다.

<details>

<summary><strong>다국어 적용 요청 본문 샘플 코드 예시</strong></summary>

```js
{
  "@context": "https://schema.org/",
  "specversion": "1.0",
  "id": "EVT-CREATE-PRODUCT",
  "type": "create_product",
  "agent": {
    "@type": "Organization",
    "name": "ExampleCorp"
  },
  "@graph": [
    {
      "@type": "Product",
      "sku": "PROD-001-A",
      "name": [
        {
          "@value": "프리미엄 블루투스 이어폰",
          "@language": "ko"
        },
        {
          "@value": "Premium Bluetooth Earphones",
          "@language": "en"
        }
      ],
      "description": [
        {
          "@type": "TextObject",
          "text": "완전 무선 블루투스 이어폰으로 고음질 사운드와 편안한 착용감을 제공합니다.",
          "inLanguage": "ko",
          "additionalProperty": [
            {
              "@type": "PropertyValue",
              "propertyID": "html",
              "value": "<p>완전 무선 블루투스 이어폰...</p>"
            }
          ]
        },
        {
          "@type": "TextObject",
          "text": "True wireless bluetooth earphones providing high-quality sound and comfortable fit.",
          "inLanguage": "en",
          "additionalProperty": [
            {
              "@type": "PropertyValue",
              "propertyID": "html",
              "value": "<p>True wireless bluetooth earphones...</p>"
            }
          ]
        }
      ],
      "brand": {
        "@type": "Brand",
        "@id": "brand-001",
        "name": [
          {
            "@value": "사운드맥스",
            "@language": "ko"
          },
          {
            "@value": "SoundMax",
            "@language": "en"
          }
        ],
        "logo": "https://example.com/brand/soundmax-logo.png"
      },
      "category": [
        {
          "@type": "CategoryCode",
          "codeValue": "ELEC001",
          "name": [
             { "@value": "전자기기", "@language": "ko" },
             { "@value": "Electronics", "@language": "en" }
          ],
          "position": 1
        },
        {
          "@type": "CategoryCode",
          "codeValue": "AUDIO005",
          "name": [
             { "@value": "오디오 기기", "@language": "ko" },
             { "@value": "Audio Devices", "@language": "en" }
          ],
          "position": 2
        }
      ],
      "positiveNotes": [
        {
          "@value": "고음질, 장시간 배터리, 편안한 착용감",
          "@language": "ko"
        },
        {
          "@value": "High fidelity, Long battery life, Comfortable fit",
          "@language": "en"
        }
      ],
      "url": [
        {
          "@value": "https://example.com/product/P001",
          "@language": "ko"
        },
        {
          "@value": "https://example.com/en/product/P001",
          "@language": "en"
        }
      ],
      "itemCondition": "NewCondition",
      "hasAdultConsideration": "UnclassifiedAdultConsideration",
      "countryOfOrigin": {
        "@type": "Country",
        "address": "KR"
      },
      "material": [
        {
          "@value": "플라스틱, 실리콘",
          "@language": "ko"
        },
        {
          "@value": "Plastic, Silicone",
          "@language": "en"
        }
      ],
      "offers": {
        "@type": "Offer",
        "sku": "PROD-001-A",
        "gtin": "8801234567890",
        "mpn": "SM-EAR-2025",
        "price": 129000,
        "priceCurrency": "KRW",
        "priceSpecification": {
          "@type": "UnitPriceSpecification",
          "price": 129000,
          "unitCode": "EA"
        },
        "availability": "InStock",
        "availabilityStarts": "2025-11-28T10:00:00Z",
        "availabliltyEnds": "2026-12-31T23:59:59Z",
        "inventoryLevel": {
          "@type": "QuantitativeValue",
          "value": 250
        },
        "shippingDetails": {
          "@type": "OfferShippingDetails",
          "weight": {
            "@type": "QuantitativeValue",
            "value": 0.2,
            "unitCode": "KG"
          }
        },
        "image": [
          {
            "@type": "ImageObject",
            "contentUrl": "https://example.com/product/P001/main.jpg",
            "contentSize": "350KB",
            "width": {
              "@type": "QuantitativeValue",
              "value": 1080
            },
            "height": {
              "@type": "QuantitativeValue",
              "value": 1080
            }
          }
        ]
      },
      "additionalProperty": [
        {
          "@type": "PropertyValue",
          "propertyID": "hsCode",
          "value": "851762"
        },
        {
          "@type": "PropertyValue",
          "propertyId": "sustainabilityTags",
          "value": ["lowEnergyConsumption", "recyclablePackaging"]
        }
      ]
    }
  ]
}
```

</details>

{% endstep %}

{% step %}

## 응답 확인하기 (Check Response)

API 호출 후 HTTP 상태 코드를 확인하여 전송 성공 여부를 판단합니다.

#### 상태 코드 (HTTP Status Codes)

가장 먼저 확인해야 할 응답 상태 코드입니다.

<table><thead><tr><th width="166.3515625">상태 코드</th><th width="117.9609375">결과</th><th>설명</th></tr></thead><tbody><tr><td>200 OK</td><td>성공</td><td>성공입니다. 다음날 00:15am 배치를 통해 반영됩니다.</td></tr><tr><td>400 Bad Request</td><td>요청 형식 오류</td><td>JSON 문법이 틀렸거나, 필수 값(<code>sku</code>, <code>name</code> 등)이 누락되었는지 확인하세요.</td></tr><tr><td>401 Unauthorized</td><td>인증 실패</td><td>Header의 <code>apiKey</code> 값이 정확한지, 공백은 없는지 확인하세요.</td></tr><tr><td>500 Internal Error</td><td>서버 오류</td><td>일시적인 장애일 수 있습니다. 잠시 후 재시도(Retry) 로직을 실행하세요.</td></tr></tbody></table>
{% endstep %}
{% endstepper %}
