> ## 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="유저-식별자-유형">
  **유저 식별자 유형**
</h3>

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

<h4 id="a-1-device-id">
  **1. Device ID**
</h4>

Device ID는 SDK를 통한 [데이터 패칭(Data Fetching)](https://developers.airbridge.io/docs/data-fetching-%EA%B0%80%EC%9D%B4%EB%93%9C%EB%9E%80)으로 수집할 수 있습니다.
운영체제별로 수집 가능한 식별자는 다음과 같습니다.

| Request Body Key  | 데이터 패칭 필드명                   | 운영체제        |
| ----------------- | ---------------------------- | ----------- |
| device.deviceUUID | Airbridge Device ID          | All         |
| device.gaid       | GAID (Google Advertising ID) | Android     |
| device.appSetID   | App Set ID                   | Android     |
| device.ifa        | IDFA                         | iOS, iPadOS |
| device.ifv        | IDFV                         | iOS, iPadOS |

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

        "device": {
            "deviceUUID": "542177F1-5C23-438B-8088-82D34C94F6D7",
            "ifa": "542177F1-5C23-438B-8088-82D34C94F6D7",
            "ifv": "37EEC3E0-BF15-412E-ADBA-7D2E82E7A75F",
            "osName": "iOS",
            "osVersion": "18.0.1"
        },
        "user": {
            "externalUserID": "19443",
            "externalUserEmail": "example@ab180.co",
            "externalUserPhone": "821012341234"
        }

        ...
    }
    ```

    ```json Android lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
    {
        ...

        "device": {
            "deviceUUID": "2dfca632-86f3-4d22-9746-cdfe7985c471",
            "gaid": "2dfca632-86f3-4d22-9746-cdfe7985c471",
            "appSetID": "7c4681ef-97c6-4ebd-9c04-e22f584b3746",
            "osName": "Android",
            "osVersion": "5.0.2"
        },
        "user": {
            "externalUserID": "19443",
            "externalUserEmail": "example@ab180.co",
            "externalUserPhone": "821012341234"
        }

        ...
    }
    ```
  </CodeGroup>
</Accordion>

<h4 id="a-2-user-id-user-externaluserid">
  **2. User ID(`user.externalUserID`)**
</h4>

SDK를 통한 데이터 패칭이 불가능한 상황에서는, Device ID 없이 User ID만 전송할 수 있습니다.
이 경우 Airbridge는 내부 데이터베이스를 이용해 해당 User ID와 연결된 Device ID를 기준으로 이벤트를 처리합니다.
하지만 User ID와 연결된 Device 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>

<h3 id="매체-연동-시-주의사항">
  **매체 연동 시 주의사항**
</h3>

<div id="광고-최적화를-위해-필요한-정보" />

<Note>
  **광고 최적화를 위해 필요한 정보**

  매체 연동을 이용하는 경우, API로 전송되는 정보가 광고 최적화 목적으로도 사용됩니다.
  이에 따라 수집 가능한 모든 정보를 API를 통해 전송하는 것이 권장됩니다.
  가장 일반적으로 최적화에 사용되는 정보는 아래와 같습니다.

  * app.packageName
  * device.osName
  * device.osVersion
  * device.appTrackingTransparency
  * device.limitAdTracking
</Note>

<h3 id="이벤트-예시">
  **이벤트 예시**
</h3>

<Accordion title="상품 구매 예시">
  ```json lines theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
  {
      "eventUUID": "9b4b3e4e-2162-4ae6-8986-91ee84644262",
      "user": {
          "externalUserID": "19443",
          "externalUserEmail": "example@ab180.co",
          "externalUserPhone": "821012341234"
      },
      "device": {
          "deviceUUID": "2dfca632-86f3-4d22-9746-cdfe7985c471",
          "gaid": "2dfca632-86f3-4d22-9746-cdfe7985c471",
          "appSetID": "7c4681ef-97c6-4ebd-9c04-e22f584b3746",
          "deviceModel": "SM-0000",
          "manufacturer": "Samsung",
          "osName": "Android",
          "osVersion": "5.0.2",
          "locale": "ko-KR",
          "timezone": "Asia/Seoul",
          "orientation": "portrait",
          "screen": {
              "width": 123
          },
          "location": {
              "latitude": 120.103,
              "speed": "12"
          },
          "network": {
              "carrier": "SKTelecom",
              "cellular": true,
              "wifi": true
          }
      },
      "app": {
          "packageName": "com.ab180.co",
          "version": "1.2.3"
      },
      "eventData": {
          "goal": {
              "category": "airbridge.ecommerce.order.completed",
              "value": 159990,
              "semanticAttributes": {
                  "action": "christmas purchase",
                  "label": "chrismas sale",
                  "transactionID": "12939172",
                  "inAppPurchased": true,
                  "currency": "KRW",
                  "products": [
                      {
                          "quantity": 1,
                          "productID": "CH129",
                          "position": 0,
                          "name": "timeless trench coat",
                          "currency": "KRW",
                          "price": 159990
                      }
                  ]
              },
              "customAttributes": {
                  "season": "chirstmas",
                  "gift": true
              }
          }
      }
  }
  ```
</Accordion>

<Card title="Try API Request" icon="rectangle-api" horizontal href="https://www.postman.com/airbridge-engineering/workspace/airbridge-api/request/22395869-0fde7701-9f8c-42bd-a7a2-d25cd4bef2ec" />

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

<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>

<ParamField header="x-airbridge-use-client-ip" type="number">
  `X-Forwarded-For` 에 사용자 IP를 전송할 수 없는 경우, Request Body에 전송한 `device.clientIP`필드로 사용자 IP를 결정할 수 있도록 합니다.

  Required when: Request Body에 device.clientIP를 전송하는 경우
</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="device" type="object">
  디바이스 정보를 담습니다.

  Required when: user.externalUserID를 전송하지 않는 경우 필수로 전송되어야합니다.

  <Expandable title="하위 변수">
    <ParamField body="device.deviceUUID" type="string">
      에어브릿지 디바이스 ID.

      GAID, IDFA, IDFV, Random Generated UUID, App Set ID를 받습니다.

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

    <ParamField body="device.gaid" type="string">
      구글에서 제공하는 광고 ID
    </ParamField>

    <ParamField body="device.ifa" type="string">
      애플에서 제공하는 광고 ID (IDFA)
    </ParamField>

    <ParamField body="device.appSetID" type="string">
      구글에서 제공하는 AppSetID.
    </ParamField>

    <ParamField body="device.ifv" type="string">
      애플에서 제공하는 IDFV.
    </ParamField>

    <ParamField body="device.clientIP" type="string">
      X-Forwarded-For 헤더에 사용자의 디바이스 IP를 전송할 수 없는 경우, 확률적 매칭을 위해 반드시 전송해야 합니다.
      요청 헤더에 `x-airbridge-use-client-ip: 1` 를 반드시 함께 포함시켜주세요.

      Required when: X-Forwarded-For 헤더에 사용자의 디바이스 IP를 전송할 수 없는 경우 확률적 모델링을 위해 전송되어야합니다.
    </ParamField>

    <ParamField body="device.limitAdTracking" type="boolean">
      안드로이드 디바이스에 설정된 광고 추적 제한 설정값입니다. 이 값은 SDK에서 수집 후 전송해야 하며, 기본값은 `true`입니다. 값이 `true`인 경우, 연동된 광고 채널에 포스트백으로 공유되는 정보가 제한됩니다.
    </ParamField>

    <ParamField body="device.deviceModel" type="string">
      디바이스 모델명.
    </ParamField>

    <ParamField body="device.appTrackingTransparency" type="integer">
      App Tracking Transparency

      | Value | ATT Status     |
      | ----- | -------------- |
      | 0     | Not Determined |
      | 1     | Restricted     |
      | 2     | Denied         |
      | 3     | Authorized     |
    </ParamField>

    <ParamField body="device.deviceIdentifier" type="string">
      iPhone11,2과 같은 구체적인 디바이스 식별자. (iPhone만 가능)
    </ParamField>

    <ParamField body="device.manufacturer" type="string">
      디바이스 제조사.
    </ParamField>

    <ParamField body="device.osName" type="enum">
      디바이스 운영체제 이름.

      Required when: device.deviceUUID를 전송하는 경우 필수로 전송되어야합니다.

      | 벨류        | 설명    |
      | --------- | ----- |
      | `Android` | 안드로이드 |
      | `iOS`     | iOS   |
    </ParamField>

    <ParamField body="device.osVersion" type="string">
      디바이스 운영체제 버전.

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

    <ParamField body="device.locale" type="string">
      BCP 47 언어 태그 형식의 디바이스 로케일 정보. (eg. `ko-KR`, `en-US`, `ja-JP`)

      Airbridge는 해당 필드로 이벤트의 국가, 언어 정보를 획득합니다.
    </ParamField>

    <ParamField body="device.timezone" type="string">
      디바이스의 타임존. IANA 데이터베이스의 Timezone Name 형식으로 사용되어야합니다. (eg. `Asia/Seoul`, `America/Los_Angeles`, `Asia/Tokyo`)
    </ParamField>

    <ParamField body="device.orientation" type="string">
      디바이스 방향.
    </ParamField>

    <ParamField body="device.screen" type="string">
      디바이스 스크린 정보.

      <Expandable title="하위 변수">
        <ParamField body="device.screen.density" type="string">
          디바이스 해상도.
        </ParamField>

        <ParamField body="device.screen.height" type="number">
          디바이스 스크린 높이.
        </ParamField>

        <ParamField body="device.screen.width" type="number">
          디바이스 스크린 너비.
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="device.alias" type="object">
      디지털 시장법(DMA)을 준수하기 위해 필요한 유저 응답 정보를 에어브릿지에 전송할 수 있습니다. DMA에 대한 자세한 내용은 [에어브릿지 가이드](/ko/guides/supporting-the-updated-google-eu-user-consent-policy)를 참고해 주세요.

      <Expandable title="하위 변수">
        <ParamField body="device.alias.eea" type="string">
          DMA를 준수해야 하는 지역에 대한 정보. `“0"`, `“1"`을 제외한 데이터는 처리되지 않습니다. 유저가 응답한 정보 또는 에어브릿지가 자동으로 수집하는 정보가 아닙니다. 실제 지역에 따라 알맞게 전송해 주세요.

          0이라면 다른 변수를 에어브릿지에 전송하지 않는 것을 권장합니다.

          * `0`: DMA 준수와 관계 없는 지역.
          * `1`: DMA를 준수해야 하는 지역.
        </ParamField>

        <ParamField body="device.alias.adPersonalization" type="string">
          개인 맞춤형 광고(Personalized Ads) 제공을 위한 정보 수집에 대한 동의 설정. `“0"`, `“1"`을 제외한 데이터는 처리되지 않습니다.

          * `0`: 유저가 동의하지 않음.
          * `1`: 유저가 동의함.
        </ParamField>

        <ParamField body="device.alias.adUserData" type="string">
          광고에 사용하는 유저 데이터를 구글에 전송하는 것에 대한 동의 설정. `“0"`, `“1"`을 제외한 데이터는 처리되지 않습니다.

          * `0`: 유저가 동의하지 않음.
          * `1`: 유저가 동의함.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="app" type="object" required>
  사용자의 앱 정보를 담습니다.

  <Expandable title="하위 변수">
    <ParamField body="app.packageName" type="string" required>
      구글 플레이 스토어 또는 애플 앱스토어에 등록된 앱의 패키지 이름. (Android: 패키지 이름, iOS: 번들 ID)
    </ParamField>

    <ParamField body="app.version" type="string">
      앱 사용자가 사용하고 있는 앱의 버전.
    </ParamField>
  </Expandable>
</ParamField>

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

  <Expandable title="하위 변수">
    <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.currency" type="string">
              결제 이벤트의 결제 통화. 이벤트 처리 과정에서 대시보드에 설정된 통화로 변환되므로 실제 결제에 사용된 통화를 사용해도 됩니다.
            </ParamField>

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

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

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

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

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

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

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

                <ParamField body="eventData.goal.semanticAttributes.products[0].quantity" type="integer">
                  상품 수량.
                </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}/mobile-app/9360' \
    -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' \
    -H 'x-airbridge-use-client-ip: 1' \
    -d '{
    "eventUUID": "9b4b3e4e-2162-4ae6-8986-91ee84644262",
    "user": {
      "externalUserID": "19443",
      "externalUserEmail": "example@ab180.co",
      "externalUserPhone": "821012341234"
    },
    "device": {
      "deviceUUID": "2dfca632-86f3-4d22-9746-cdfe7985c471",
      "gaid": "2dfca632-86f3-4d22-9746-cdfe7985c471",
      "ifa": "542177F1-5C23-438B-8088-82D34C94F6D7",
      "appSetID": "7c4681ef-97c6-4ebd-9c04-e22f584b3746",
      "ifv": "37EEC3E0-BF15-412E-ADBA-7D2E82E7A75F",
      "clientIP": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
      "limitAdTracking": true,
      "deviceModel": "LG-H542",
      "appTrackingTransparency": 0,
      "deviceIdentifier": "iPhone11,2",
      "manufacturer": "Samsung",
      "osName": "Android",
      "osVersion": "5.0.2",
      "locale": "ko-KR",
      "timezone": "Asia/Seoul",
      "orientation": "portrait",
      "screen": {
        "width": 123
      }
    },
    "app": {
      "packageName": "com.ab180.co",
      "version": "1.2.3"
    },
    "eventData": {
      "goal": {
        "category": "airbridge.ecommerce.product.addedToCart",
        "value": 159990,
        "semanticAttributes": {
          "currency": "KRW",
          "action": "shoes",
          "label": "nike",
          "transactionID": "12939172",
          "inAppPurchased": true,
          "products": [
            {
              "currency": "KRW",
              "productID": "30372425",
              "price": 10990,
              "name": "나이키 커스텀",
              "position": "1",
              "quantity": 1
            }
          ]
        }
      }
    }
  }'
  ```
</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(9360) 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>
