Amplitude HTTP API 수집

Amplitude HTTP API 수집

Amplitude의 HTTP V2 API(이벤트 수집 엔드포인트)는 서버에서 애널리틱스 이벤트 데이터를 직접 Amplitude로 보낼 때 사용해요. 요청 본문에 api_key와 이벤트 배열(events)을 JSON으로 담아 수집 엔드포인트에 POST하면 되고, 이벤트별 사용자/디바이스 ID와 이벤트 타입을 넣을 수 있어요. 서버 측 이벤트 수집의 주된 방법이며, 고처리량 데이터 수집과 내장 검증, 에러 리포팅까지 지원한답니다. 예전 developers.amplitude.com/docs/http-api/ingestion/ 문서는 현재 이 HTTP V2 API 페이지로 이전됐어요.

출처: 문서

본문

리전(Region)과 베이스 URL

베이스 URL은 프로젝트의 데이터 리전(data residency)에 따라 달라져요. 기본적으로 이벤트 수집 호스트는 api2.amplitude.com이며, EU 데이터 센터를 쓰는 프로젝트라면 api.eu.amplitude.com을 사용해요. 다른 Amplitude API(api.amplitude.com, core.amplitude.com, data-api.amplitude.com, experiment.amplitude.com 등)와는 호스트가 다르다는 점을 주의하세요. https://analytics.amplitude.com은 Analytics 웹앱(브라우저 UI)이라 수집 엔드포인트가 아니에요.

데이터 리전 베이스 URL
Default https://api2.amplitude.com
EU https://api.eu.amplitude.com

엔드포인트와 인증

이벤트 한 건 또는 여러 건(배치)을 업로드하려면 엔드포인트에 POST 요청을 보내요. 인증 방식으로는 Amplitude 프로젝트의 API Key(api_key)를 사용해요. API Key는 본문의 api_key 필드에 넣으면 돼요.

POST https://api2.amplitude.com/2/httpapi

헤더로는 Content-Type: application/json을 지정해요.

업로드 제한(Upload limit)

  • Free 플랜: 초당 100배치, 초당 1000이벤트로 제한돼요. 배치 하나에 이벤트를 모아 보낼 수 있지만 Amplitude는 배치당 10개 이하를 권장해요.
  • Growth/Enterprise 플랜: 요청 크기를 1MB 미만, 요청당 이벤트 2000개 미만으로 유지해요. 이 제한을 넘으면 413 에러가 나요.
  • 프로젝트당 HTTP API/HTTP V2 엔드포인트 처리 상한은 초당 50,000이벤트예요(비교: SDK 엔드포인트는 프로젝트당 초당 150,000이벤트).
  • 트래픽이 많다면 device_iduser_id 기준으로 파티셔닝해 스로틀링(throttling)이 일부 전송자에만 영향을 주도록 해요.

참고 사항

  • Rate limiting: Amplitude는 (Amplitude ID 기준) 사용자 프로퍼티를 시간당 1800회 넘게 업데이트하는 개별 사용자를 제한해요. 이는 사용자 프로퍼티 동기화에 대한 제한이며 이벤트 수집에는 적용되지 않아요.
  • 문자 제한: user_id, 이벤트, 사용자 프로퍼티 등 모든 문자열 값은 1024자 제한이 있어요.
  • 날짜 값: Amplitude는 날짜를 문자열로 비교해요. ISO 8601 형식(YYYY-MM-DDTHH:mm:ss)을 사용하면 날짜 비교가 가능해요.
  • 시간 값: 각 이벤트의 time은 epoch 이후 **밀리초(ms)**로 보내야 해요. 다른 형식(예: ISO)이면 400 Bad Request가 반환돼요.
  • 이벤트 중복 제거(dedup): 각 이벤트에 insert_id를 보내 중복 전송을 막는 걸 강력히 권장해요. 같은 device_id(이벤트에 device_id가 있는 경우)와 같은 insert_id로 최근 7일 안에 다시 보내면 Amplitude가 무시해요.
  • ID 최소 길이: device_iduser_id는 5자 이상 문자열이어야 해요. 더 짧으면 Amplitude가 해당 ID 값을 이벤트에서 제거해요. 기본 최소 길이 5는 min_id_length 옵션으로 재정의할 수 있어요.
  • Windows: Windows OS를 쓴다면 모든 작은따옴표를 이스케이프된 큰따옴표로 바꿔야 할 수 있어요.
  • iOS Zero device ID: iOS 10부터 사용자가 'Limit Ad Tracking'을 켜면 IDFA가 전부 0으로 바뀌어요. 모든 이벤트는 디바이스 ID가 필요하므로, Amplitude는 전부 0인 디바이스 ID를 버리고 요청에 에러를 반환해요. IDFA가 전부 0이라면 IDFV 같은 다른 값을 넣어야 해요.

요청 예시: 기본 요청

사용자 12345에 대해 watch_tutorial 이벤트와 몇 가지 사용자 프로퍼티를 업로드하는 예시예요.

cURL

curl --location --request POST 'https://api2.amplitude.com/2/httpapi' \
--header 'Content-Type: application/json' \
--data-raw '{
    "api_key": "YOUR_API_KEY",
    "events": [
        {
            "user_id": "12345",
            "event_type": "watch_tutorial",
            "user_properties": {
                "Cohort": "Test A"
            },
            "country": "United States",
            "ip": "127.0.0.1",
            "time": 1396381378123
        }
    ]
}'

HTTP

POST /2/httpapi HTTP/1.1
Host: api.amplitude.com
Content-Type: application/json
Content-Length: 360

{
    "api_key": "YOUR_API_KEY",
    "events": [
        {
            "user_id": "12345",
            "event_type": "watch_tutorial",
            "user_properties": {
                "Cohort": "Test A"
            },
            "country": "United States",
            "ip": "127.0.0.1",
            "time": 1396381378123
        }
    ]
}

요청 예시: 많은 필드를 포함한 요청

여러 이벤트 프로퍼티와 사용자 프로퍼티를 포함한 watch_tutorial 이벤트 업로드 예시예요.

cURL

curl --location --request POST 'https://api2.amplitude.com/2/httpapi' \
--header 'Content-Type: application/json' \
--data-raw '{
  "api_key": "YOUR_API_KEY",
  "events": [
    {
      "user_id": "[email protected]",
      "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D",
      "event_type": "watch_tutorial",
      "time": 1396381378123,
      "event_properties": {
        "load_time": 0.8371,
        "source": "notification",
        "dates": [
          "monday",
          "tuesday"
        ]
      },
      "user_properties": {
        "age": 25,
        "gender": "female",
        "interests": [
          "chess",
          "football",
          "music"
        ]
      },
      "groups": {
        "team_id": "1",
        "company_name": [
          "Amplitude",
          "DataMonster"
        ]
      },
      "app_version": "2.1.3",
      "platform": "iOS",
      "os_name": "Android",
      "os_version": "4.2.2",
      "device_brand": "Verizon",
      "device_manufacturer": "Apple",
      "device_model": "iPhone 9,1",
      "carrier": "Verizon",
      "country": "United States",
      "region": "California",
      "city": "San Francisco",
      "dma": "San Francisco-Oakland-San Jose, CA",
      "language": "English",
      "price": 4.99,
      "quantity": 3,
      "revenue": -1.99,
      "productId": "Google Pay Store Product Id",
      "revenueType": "Refund",
      "location_lat": 37.77,
      "location_lng": -122.39,
      "ip": "127.0.0.1",
      "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "android_app_set_id": "087e666f-72f3-4d6c-8cce-e8bedce9304e",
      "event_id": 23,
      "session_id": 1396381378123,
      "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841"
    }
  ]
}'

요청 파라미터

Content-Type 헤더를 application/json으로 설정해야 해요.

본문(Body) 파라미터

Name Description
api_key Required. String. Amplitude 프로젝트 API key.
events Required. []. 업로드할 이벤트(Events) 배열.
options Optional. []. Object.

이벤트 배열 키(Event array keys)user_id 또는 device_id 중 하나는 필수이고, event_type은 필수예요. session_id 같은 프로퍼티는 이벤트 페이로드의 최상위에 넣어야 해요.

Name Description
user_id device_id를 쓰지 않으면 Required. String. 사용자 ID. min_id_length 옵션으로 바꾸지 않는 한 최소 5자.
device_id user_id를 쓰지 않으면 Required. String. 디바이스 식별자(iOS의 Identifier for Vendor 등). 이벤트에 없으면 user_id의 해시값으로 설정돼요.
event_type Required. String. 이벤트의 고유 식별자. 내부용 예약 이름: [Amplitude] Start Session, [Amplitude] End Session, [Amplitude] Revenue, [Amplitude] Revenue (Verified), [Amplitude] Revenue (Unverified), [Amplitude] Merged User. $identify / $groupidentify는 식별·그룹 식별용으로 예정돼 있어요.
user_agent Optional. 사용자 디바이스의 파싱되지 않은 user agent 문자열. Amplitude가 이를 파싱해 사용자 프로퍼티로 변환해요.
time Optional. epoch 이후 밀리초 단위 이벤트 타임스탬프. 보내지 않으면 요청 업로드 시각으로 설정돼요.
event_properties Optional. Object. 이벤트와 함께 보낼 키-값 쌍. 배열로 값을 저장할 수 있고, 날짜 값은 문자열로 변환돼요. 객체 깊이는 40계층을 넘을 수 없어요.
user_properties Optional. Object. 사용자에 연결된 데이터의 키-값 쌍. 배열 저장 가능, 날짜 값은 문자열 변환. event_type$identify일 때 사용자 프로퍼티 연산($set, $setOnce, $add, $append, $unset)을 지원해요.
groups Optional. Object. Growth/Enterprise + Accounts 애드온 고객용. 사용자 그룹을 나타내는 키-값 쌍. 이벤트당 최대 5개 그룹 타입, 총 10개 그룹 값까지 추적돼요.
group_properties Optional. Object. Accounts 애드온 고객용. event_type$groupidentify일 때 groups 필드에 연결된 프로퍼티. 그 외 이벤트 타입에선 무시돼요.
$skip_user_properties_sync Optional. Boolean. true면 사용자 프로퍼티가 동기화되지 않아요. 기본 false.
app_version, platform, os_name, os_version, device_brand, device_manufacturer, device_model, carrier, country, region, city, dma, language Optional. String. 각각 앱 버전, 플랫폼, OS 이름/버전, 디바이스 브랜드/제조사/모델, 통신사, 국가, 지역, 도시, DMA, 언어.
price Optional. Float. 구매 상품 가격. 매출 데이터에 revenue가 없으면 필수. 환불은 음수 사용.
quantity Optional. Integer. 구매 수량. 미지정 시 기본 1.
revenue Optional. Float. Revenue = (price × quantity). price, quantity, revenue 3개를 모두 보내면 revenue는 (price × quantity)예요. 환불은 음수.
productId Optional. String. 구매 상품 식별자. 이 필드와 함께 price·quantity 또는 revenue를 보내야 해요.
revenueType Optional. String. 구매 상품의 매출 유형. price·quantity 또는 revenue와 함께 보내야 해요.
currency Optional. String. 구매 상품 통화. 대문자 ISO 4217 코드(예: USD, EUR).
location_lat, location_lng Optional. Float. 사용자의 위도/경도.
ip Optional. String. 사용자의 IP 주소. $remote를 쓰면 업로드 요청의 IP 주소를 사용해요. Amplitude는 IP로 위치(도시, 국가, 지역, DMA)를 역조회해요.
idfa, idfv, adid, android_id, android_app_set_id Optional. String. 각 플랫폼별 광고/디바이스 식별자.
event_id Optional. Integer. 같은 user_id와 타임스탬프의 이벤트를 구분하는 증가 카운터. 동시 발생 이벤트가 예상되면 event_id를 시간순으로 보내는 걸 권장해요.
session_id Optional. Long. 세션 시작 시각(epoch 이후 밀리초). -1은 미지정과 같아요.
insert_id Optional. String. 이벤트 고유 식별자. 같은 device_idinsert_id로 7일 안에 다시 보내면 중복 제거돼요. UUID 또는 device_id·user_id·event_type·event_id·time 조합을 권장해요.
plan Optional. Object. 트래킹 플랜 프로퍼티. branch, source, version만 지원해요.
plan.branch / plan.source / plan.version Optional. String. 트래킹 플랜 브랜치/소스/버전.

Options

Name Description
min_id_length Optional. Integer. user_id·device_id의 기본 최소 길이 5를 재정의해요.

응답(Response)

insert_id(같은 이벤트 중복 제거용)를 보내고 재시도(retry) 로직을 구현하길 권장해요. 이렇게 하면 API가 불가하거나 요청이 실패해도 이벤트 유실·중복을 막을 수 있어요. 200 이외 응답을 잡도록 자체 로깅을 추가하는 것도 권장해요.

200 OK — 성공적인 실시간 이벤트 업로드. 200 OK를 받지 못하면 요청을 재시도해요.

{
  "code": 200,
  "events_ingested": 50,
  "payload_size_bytes": 50,
  "server_upload_time": 1396381378123
}
Name Description
code Integer. 200 성공 코드
events_ingested Integer. 업로드 요청에서 수집된 이벤트 수
payload_size_bytes Integer. 업로드 요청 페이로드 크기(바이트)
server_upload_time Long. Amplitude 이벤트 서버가 업로드를 수락한 시각(epoch 이후 밀리초)

400 Bad Request — 잘못된 업로드 요청. 응답을 확인해 주세요. 원인 예시: 본문이 유효한 JSON이 아님(error: Invalid JSON request body), 필수 필드 누락(error: Request missing required field), 이벤트 객체의 잘못된 필드(events_with_invalid_fields가 필드명을 오류가 난 첫 이벤트의 인덱스로 매핑), 일부 디바이스가 silenced 상태.

{
  "code": 400,
  "error": "Request missing required field",
  "missing_field": "api_key",
  "events_with_missing_fields": {
    "event_type": [3]
  }
}

403 Forbidden — WAF(웹 애플리케이션 방화벽)가 요청을 차단했어요. 헤더/본문/URI에 Amplitude 보안 필터에 걸리는 값이 있거나, Amplitude가 요청을 받을 수 없는 제재 지역에서 온 경우예요.

{
  "code": 403,
  "error": "Forbidden"
}

413 Payload Too Large — 페이로드가 너무 큼(요청 크기 1MB 초과). 이벤트 배열 페이로드를 여러 요청으로 나눠 다시 시도해요.

{
  "code": 413,
  "error": "Payload too large"
}

429 Too Many Requests — 사용자나 디바이스에 대한 요청이 너무 많음. Amplitude는 최근 시간 창에서 평균으로 계산했을 때 초당 30이벤트를 넘는 사용자/디바이스를 스로틀링해요. 30초간 멈췄다가 재시도하고, 429를 받지 않을 때까지 계속해요.

{
  "code": 429,
  "error": "Too many requests for some devices and users",
  "eps_threshold": 30,
  "throttled_devices": {
    "C8F9E604-F01A-4BD9-95C6-8E5357DF265D": 31
  },
  "throttled_users": {
    "[email protected]": 32
  },
  "throttled_events": [3, 4, 7]
}

500, 502, 504 Server Error — Amplitude가 요청 처리 중 오류 발생. 이 응답을 받은 요청은 수락되지 않았을 수 있어요. 재시도하면 이벤트가 중복될 수 있으므로 insert_id를 보내 중복을 막아요.

503 Service Unavailable — Amplitude 내부 문제로 요청 실패. 재시도해도 이벤트가 중복될 위험은 없어요.

더 알아보기 (Learn more)