> ## Documentation Index
> Fetch the complete documentation index at: https://help.airbridge.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 인웹 이벤트 전송하기

Server-to-Server 방식으로 인웹 이벤트를 전송합니다.

rate limit : 분당 1000회 요청으로 제한됩니다.

<h3 id="유저-식별자-유형-2">
  **유저 식별자 유형**
</h3>

<Danger>
  유저 식별자는 일관적인 기여, 포스트백, 코호트 집계 등에 필수적이며 이에 따라 수집 가능한 모든 식별자를 전송하는 것이 권장됩니다.
</Danger>

<h4 id="i-cookie-id-browser-clientid">
  I**⁠. Cookie ID(`browser.clientID`)**
</h4>

Cookie ID는 SDK를 통한 [데이터 패칭(Data Fetching)](https://developers.airbridge.io/docs/data-fetching-%EA%B0%80%EC%9D%B4%EB%93%9C%EB%9E%80)으로 수집할 수 있습니다.
이 때 Cookie ID와 함께 아래 데이터를 수집하여 Airbridge 서버로 전송해야 정확히 기여처리 될 수 있습니다.

| 파라미터                           | 데이터 패칭 필드명                     | 설명          |
| ------------------------------ | ------------------------------ | ----------- |
| eventData.shortID              | Attribution Short ID           | 캠페인 파라미터 ID |
| eventData.trackingData.channel | Default Attribution Channel    | 캠페인 채널      |
| eventData.trackingData.params  | Default Attribution Parameters | 캠페인 파라미터    |

<Accordion title="전송 예시">
  ```json lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  {
    ...

    "browser": {
      "clientID": "05609013-bb5a-4594-bbc3-832cb1b87072"
    },
    "eventData": {
      "shortID": "aef04",
      "trackingData": {
        "channel": "blog",
        "params": {
          "ad_creative": "ad_creative",
          "ad_group": "ad_group",
          "campaign": "ad_campaign",
          "content": "ad_content",
          "medium": "ad_medium",
          "tracking_template_id": "ad_tracking_template_id"
        }
      }
    },
    "user": {
      "externalUserID": "19443",
      "externalUserEmail": "example@ab180.co",
      "externalUserPhone": "821012341234"
    }
    
    ...
  }
  ```
</Accordion>

<h4 id="ii-user-id-user-externaluserid">
  II**⁠. User ID(`user.externalUserID`)**
</h4>

데이터 패칭이 불가능한 상황에서는, Cookie ID 없이 User ID만 전송할 수 있습니다.
이 경우 Airbridge는 내부 데이터베이스를 이용해 해당 User ID와 연결된 Cookie ID를 기준으로 이벤트를 처리합니다.
하지만 User ID와 연결된 Cookie ID가 없는 경우, 리포트의 정확도가 떨어질 수 있습니다.

<Accordion title="전송 예시">
  ```json lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  {
      ...
      
      "user": {
          "externalUserID": "19443",
          "externalUserEmail": "example@ab180.co",
          "externalUserPhone": "821012341234"
      }

      ...
  }

  ```
</Accordion>

<Card title="Try API Request" icon="rectangle-api" horizontal href="https://www.postman.com/airbridge-engineering/workspace/airbridge-api/request/22395869-c04f0ec2-cd2e-4e28-b7e9-04b57fae50ed" />

```text POST theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
https://api.airbridge.io/events/v2/apps/{app_name}/web/9320
```

<h2 id="인웹-이벤트-전송하기-request">
  Request
</h2>

***

<h3 id="인웹-이벤트-전송하기-headers">
  Headers
</h3>

<ParamField header="Accept-Language" type="string">
  API 요청 및 결과 반환에 사용할 언어를 지정할 수 있습니다. ISO-639-1 포맷을 따릅니다.
</ParamField>

<ParamField header="Content-Type" type="string">
  리소스의 미디어 타입을 나타냅니다. 기본값으로 `application/json`을 사용합니다.
</ParamField>

<ParamField header="Authorization" type="string">
  API 요청에 사용하는 키값입니다. [키값 생성 및 조회 방법](/ko/references/introduction)을 확인하여 획득할 수 있습니다.
</ParamField>

<ParamField header="X-Forwarded-For" type="string" required>
  사용자의 IP를 X-Forwarded-For 헤더로 보낼 수 있습니다. X-Forwarded-For가 없는 경우 사용자의 IP(클라이언트 요청 IP)가 아닌 Server To Server API를 요청한 서버의 IP로 사용자 행동이 기록됩니다.

  ipv4(`123.123.123.123`), ipv6(`2001:e60:87e3:81d4:cd57:5d52:ee2e:ff8d`) 형태의 값을 받습니다.
</ParamField>

<h3 id="인웹-이벤트-전송하기-path-params">
  Path Params
</h3>

<ParamField path="app_name" type="string" required>
  에어브릿지 앱 이름(App Name)
</ParamField>

<h3 id="인웹-이벤트-전송하기-body-params">
  Body Params
</h3>

<ParamField body="eventUUID" type="string">
  고유 이벤트 ID.

  uuid4 포맷의 event uuid는 이벤트 고유 ID로 Deduplication에 사용되며, 넣지 않으면 event api에서 자동 생성하게 됩니다.
</ParamField>

<ParamField body="eventTimestamp" type="number">
  이벤트 발생 시간. (기본값: 현재 시간)

  Millisecond 단위의 Unix Timestamp입니다. (Unixtime 기준 13자리)

  **eventTimestamp가 이벤트 전송 시점 기준으로 24시간을 지나면 서버에서 처리하지 않습니다.**
</ParamField>

<ParamField body="user" type="object">
  유저에 관한 정보를 담을 수 있습니다.

  <Expandable title="하위 변수">
    <ParamField body="user.externalUserID" type="string">
      사용자 아이디.

      Required when: device.deviceUUID를 전송하지 않는 경우 필수로 전송되어야합니다.
    </ParamField>

    <ParamField body="user.externalUserEmail" type="string">
      사용자 이메일.
    </ParamField>

    <ParamField body="user.externalUserPhone" type="string">
      사용자 전화번호.
    </ParamField>

    <ParamField body="user.attributes" type="object">
      커스텀 사용자 속성.

      JSON 형태의 데이터를 받습니다.

      `{ "age_group": "30", "brand": "Nike" }`
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="browser" type="object">
  브라우저 정보를 담을 수 있습니다.

  <Expandable title="하위 변수">
    <ParamField body="browser.clientID" type="string" required>
      브라우저 쿠키 아이디. SDK에서 Fetching한 값이 필요합니다. [관련 문서](https://developers.airbridge.io/docs/data-fetching-guide-for-web-sdk#cookie-id)

      Data Fetching이 불가능한 경우 User ID(`user.externalUserID`)를 전송하는 조건으로 생략할 수 있습니다.
    </ParamField>

    <ParamField body="browser.userAgent" type="string">
      브라우저의 유저 에이전트.

      해당 값은 이벤트의 운영체제(OS Name, Version), 플랫폼(Platform)을 결정하는 것에 사용되며, Data Fetching을 통해 수집할 수 있습니다. [관련 문서](https://developers.airbridge.io/docs/data-fetching-guide-for-web-sdk#cookie-id)
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="eventData" type="object" required>
  에어브릿지에 전송할 이벤트를 정의하는 객체입니다.

  <Expandable title="하위 변수">
    <ParamField body="eventData.shortID" type="string" required>
      어트리뷰션 캠페인 파라미터 ID. SDK Data Fetching을 통해 획득한 값을 전송하여야합니다.

      **중요:** 이 값은 처리나 여과 없이 에어브릿지 서버로 전송되어야합니다.

      Data Fetching이 불가능한 경우 User ID(`user.externalUserID`)를 전송하는 조건으로 생략할 수 있습니다.
    </ParamField>

    <ParamField body="eventData.trackingData" type="object" required>
      에어브릿지의 어트리뷰션에 적용할 데이터를 담을 수 있습니다.

      <Expandable title="하위 변수">
        <ParamField body="eventData.trackingData.channel" type="string" required>
          어트리뷰션 캠페인 채널. SDK Data Fetching을 통해 획득한 값을 전송하여야합니다.

          **중요:** 이 값은 처리나 여과 없이 에어브릿지 서버로 전송되어야합니다. (eg. `airbridge.websdk`와 같은 값도 전송되어야합니다)

          Data Fetching이 불가능한 경우 User ID(`user.externalUserID`)를 전송하는 조건으로 생략할 수 있습니다.
        </ParamField>

        <ParamField body="eventData.trackingData.params" type="object" required>
          어트리뷰션 캠페인 파라미터.

          `{"medium: "posting", campaign: "blog", term: "airbridge", content: "martech-solution"}`

          SDK Data Fetching을 통해 획득한 값을 전송하여야합니다.

          **중요:** 이 값은 처리나 여과 없이 에어브릿지 서버로 전송되어야합니다.

          Data Fetching이 불가능한 경우 User ID(`user.externalUserID`)를 전송하는 조건으로 생략할 수 있습니다.
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="eventData.goal" type="object" required>
      이벤트에 관한 정보를 담을 수 있는 객체입니다.
      카테고리, 액션, 라벨, 밸류, 시맨틱 어트리뷰트(Semantic Attributes)를 담을 수 있습니다.
      ([관련 가이드](/ko/guides/airbridge-event))

      <Expandable title="하위 변수">
        <ParamField body="eventData.goal.category" type="string" required>
          에어브릿지 이벤트의 카테고리. 이벤트 이름과 동일합니다. ([관련 가이드](/ko/guides/airbridge-event-types))
        </ParamField>

        <ParamField body="eventData.goal.value" type="number">
          이벤트의 가치.

          상품 구매, 조회 이벤트의 상품 가격이나, Ad Impression의 광고 수익과 같은 정보를 표현할 수 있습니다.
        </ParamField>

        <ParamField body="eventData.goal.customAttributes" type="object">
          커스텀 이벤트 속성.

          `{ "color": "red" }`
        </ParamField>

        <ParamField body="eventData.goal.semanticAttributes" type="object">
          [Semantic Attributes](https://abit.ly/recomended-semantic-attributes). 에어브릿지가 수집할 데이터를 미리 정의한 속성입니다.

          <Expandable title="하위 변수">
            <ParamField body="eventData.goal.semanticAttributes.action" type="string">
              에어브릿지 이벤트의 첫 번째 프로퍼티
            </ParamField>

            <ParamField body="eventData.goal.semanticAttributes.label" type="string">
              에어브릿지 이벤트의 두 번째 프로퍼티
            </ParamField>

            <ParamField body="eventData.goal.semanticAttributes.query" type="string">
              사용자 검색 쿼리.
            </ParamField>

            <ParamField body="eventData.goal.semanticAttributes.productListID" type="string">
              상품 리스트 ID.
            </ParamField>

            <ParamField body="eventData.goal.semanticAttributes.cartID" type="string">
              장바구니 ID.
            </ParamField>

            <ParamField body="eventData.goal.semanticAttributes.transactionID" type="string">
              거래 고유번호.
            </ParamField>

            <ParamField body="eventData.goal.semanticAttributes.inAppPurchased" type="boolean">
              In-app 구매 여부.

              * true : In-app 구매
              * false : In-app 구매 아님
            </ParamField>

            <ParamField body="eventData.goal.semanticAttributes.currency" type="string">
              결제 이벤트의 결제 통화. 이벤트 처리 과정에서 대시보드에 설정된 통화로 변환되므로 실제 결제에 사용된 통화를 사용해도 됩니다.
            </ParamField>

            <ParamField body="eventData.goal.semanticAttributes.products" type="object[]">
              상품에 대한 정보를 리스트로 담을 수 있습니다.

              <Expandable title="하위 변수">
                <ParamField body="eventData.goal.semanticAttributes.products[0].position" type="string">
                  상품 위치.
                </ParamField>

                <ParamField body="eventData.goal.semanticAttributes.products[0].productID" type="string">
                  상품 ID.
                </ParamField>

                <ParamField body="eventData.goal.semanticAttributes.products[0].name" type="string">
                  상품 이름.
                </ParamField>

                <ParamField body="eventData.goal.semanticAttributes.products[0].price" type="number">
                  상품 가격.
                </ParamField>

                <ParamField body="eventData.goal.semanticAttributes.products[0].quantity" type="integer">
                  상품 수량.
                </ParamField>

                <ParamField body="eventData.goal.semanticAttributes.products[0].currency" type="string">
                  상품 가격의 통화
                </ParamField>
              </Expandable>
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<RequestExample>
  ```shellscript Request theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  curl -X POST 'https://api.airbridge.io/events/v2/apps/{app_name}/web/9320' \
    -H 'Accept-Language: ko' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer {AIRBRIDGE-API-TOKEN}' \
    -H 'X-Forwarded-For: 2001:e60:87e3:81d4:cd57:5d52:ee2e:ff8d' \
    -d '{
    "eventUUID": "9b4b3e4e-2162-4ae6-8986-91ee84644262",
    "user": {
      "externalUserID": "19443",
      "externalUserEmail": "example@ab180.co",
      "externalUserPhone": "821012341234"
    },
    "browser": {
      "clientID": "05609013-bb5a-4594-bbc3-832cb1b87072",
      "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E302"
    },
    "eventData": {
      "shortID": "aef04",
      "trackingData": {
        "channel": "blog"
      },
      "goal": {
        "category": "airbridge.ecommerce.product.addedToCart",
        "value": 159990,
        "semanticAttributes": {
          "action": "shoes",
          "label": "nike",
          "query": "나이키",
          "transactionID": "12939172",
          "inAppPurchased": true,
          "currency": "KRW",
          "products": [
            {
              "position": "1",
              "productID": "30372425",
              "name": "나이키 커스텀",
              "price": 10990,
              "quantity": 1,
              "currency": "KRW"
            }
          ]
        }
      }
    }
  }'
  ```
</RequestExample>

<h2 id="인웹-이벤트-전송하기-response">
  Response
</h2>

***

### 200

### 400

잘못된 요청 시. (timestamp, sdk signature, app name 등)

### 401

잘못된 인증 토큰 사용 시.

<ResponseExample>
  ```json 200 theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  {
    "at": "2020-02-06 16:06:49",
    "data": "Event(9320) is successfully proccessed."
  }
  ```

  ```json 400 theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  {
    "at": "2020-02-06 16:06:49",
    "error": "invalid_request",
    "ingested": 0
  }
  ```

  ```json 401 theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  {
    "at": "2020-02-06 16:06:49",
    "error": "unauthorized",
    "ingested": 0
  }
  ```
</ResponseExample>
