> For the complete documentation index, see [llms.txt](https://www.analytics-docs.laplacetec.com/guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.analytics-docs.laplacetec.com/guide/startguide/connect/push-ingestion.md).

# Push API 연결

{% hint style="info" %}
이 문서는 라플라스가 제공하지 않는 채널의 데이터를 **고객사 서버에서 직접 전송**하고 싶은 경우를 위한 개발자 가이드예요. 화면에서 클릭만으로 연결하는 다른 채널 연동과 달리, 고객사 쪽 개발이 필요합니다.
{% endhint %}

## 연결 시작하기

1. 화면 좌측의 **\[데이터 연결]** 에서 **\[API 직접 적재]** 를 눌러 새 연결을 추가해 주세요. 연결 이름·데이터 종류·소스 이름을 입력하고 **\[생성]** 을 누르면, 그 화면에 **전송 주소**(아래 엔드포인트의 `{ingest_key}` 자리가 이미 채워진 전체 URL)와 **데이터 소스 ID** 가 표시돼요. 두 값 모두 복사 버튼으로 바로 복사할 수 있어요.
2. **\[설정] → \[API 연동] → \[API 키]** 에서 **\[+ 키 발급]** 으로 `Laplace-Api-Key` 를 발급받으세요. API 키 발급은 프로젝트 오너 + Growth 이상 요금제에서만 가능해요. 발급된 키는 90일 후 만료되니 그 전에 재발급해 주세요. 발급된 키는 그 자리에서 한 번만 표시되니 안전한 곳에 저장해 주세요.

## 엔드포인트

```
POST https://api.gateway.laplacetec.com/v1/ingest/{ingest_key}
```

* `ingest_key` 는 별도로 표시되는 값이 아니라, 위 1번의 생성 화면에서 안내되는 **전송 주소** URL에 이미 포함되어 있어요. 그 주소를 그대로 쓰면 돼요.

### 필수 헤더

| 헤더                       | 설명                                                                           |
| ------------------------ | ---------------------------------------------------------------------------- |
| `Laplace-Api-Key`        | 위 2번에서 발급받은 API 키                                                            |
| `Laplace-Data-Source-Id` | 데이터를 적재할 소스 ID (숫자). 한 요청은 하나의 소스로만 보낼 수 있어요. 레코드마다 소스를 섞어 보낼 수 없습니다.        |
| `Idempotency-Key`        | 배치(요청) 단위로 고유한 값 (ASCII 출력 가능 문자, 최대 255바이트). **재개(재시도) 방법**에서 쓰이는 핵심 헤더입니다. |
| `Content-Encoding: gzip` | 본문은 항상 gzip 압축이어야 해요.                                                        |

### 본문

* 기본: NDJSON(줄바꿈으로 구분된 JSON 레코드, `Content-Type: application/x-ndjson`). `Content-Type: application/json` 을 함께 보내면 JSON 배열 형식도 허용됩니다.
* 각 레코드는 `{"_insert_id": "<레코드 고유 ID>", "data": {...}}` 형태여야 해요. `data` 객체가 없는 레코드가 하나라도 있으면 요청 전체가 `400` 으로 거부됩니다.
* 레코드당 최대 1MiB, 요청(압축 해제 기준) 최대 10MiB, 최대 2,000 레코드.

성공 시 `202 Accepted` 와 함께 `{"batch_id": "..."}` 를 반환합니다. `batch_id` 는 전송한 배치를 가리키는 식별자이니, 보내신 쪽 로그에 남겨 두시면 문의하실 때 도움이 됩니다.

{% hint style="warning" %}
전송 결과를 조회하는 API 는 제공하지 않아요. 접수 여부는 **\[데이터 연결] → \[API 직접 적재]** 화면의 **배치 현황** 표에서 바로 확인할 수 있지만, **몇 건이 통과했는지는 검증이 끝난 뒤에야 채워집니다.** 그 전까지 통과·거부 칸은 `-` 로 보여요. 아래 「배치 현황 보는 방법」을 참고해 주세요.
{% endhint %}

## 분당 호출 제한

**분당 10회를 넘지 않도록 클라이언트를 설계해 주세요.** 이 한도를 초과하면 `429 Too Many Requests` 를 반환할 수 있어요.

{% hint style="warning" %}
가끔 분당 10회를 살짝 넘겨도 일시적으로 통과하는 것처럼 보일 수 있지만, 이는 보장된 동작이 아니라 언제든 `429` 로 막힐 수 있어요. **처음부터 분당 10회 이하로 여유 있게 설계해 주세요.**
{% endhint %}

`429` 응답에는 다음 헤더가 함께 내려갑니다.

| 헤더                    | 의미                         |
| --------------------- | -------------------------- |
| `Retry-After`         | 이 초(seconds) 이후 재시도하면 됩니다. |
| `RateLimit-Remaining` | 현재 시간 창에서 남은 호출 가능 횟수.     |
| `RateLimit-Reset`     | 카운터가 초기화되기까지 남은 시간(초).     |

## 429 를 받았을 때 재개하는 방법

**절대 처음부터 전량 재전송하지 마세요.** 아래 순서로 진행하면 이미 접수된 배치를 다시 보내지 않습니다.

1. **같은 `Idempotency-Key` 로 재시도하세요.** 같은 키 + 같은 본문으로 다시 보내면, 서버는 이미 처리한 배치라면 재처리 없이 기존 결과를 그대로 돌려줍니다. 배치를 나눠 보낼 때는 배치마다(예: 파일 해시, 청크 번호 기반) 안정적인 키를 미리 정해 두세요.
2. **`Retry-After` 헤더의 초만큼 대기한 뒤** 같은 요청을 다시 보내세요.
3. 어디까지 전송됐는지 확실하지 않아도, **1번을 지켰다면 처음 배치부터 순서대로 다시 보내도 안전합니다.** 이미 접수된 배치는 같은 `Idempotency-Key` 때문에 서버가 다시 처리하지 않아요. 반대로 키를 배치마다 새로 만들어 보내면 같은 데이터가 중복 적재되니, 키 고정이 재개의 전부입니다.

{% hint style="danger" %}
`429` 를 받고 재개 지점을 몰라 이미 접수된 배치까지 포함해 처음부터 전량 재전송하면, 그만큼 불필요한 트래픽과 처리 대기가 발생해요. `Idempotency-Key` 를 배치마다 고정해 두면 이런 재전송도 서버가 안전하게 무시(중복 미처리)합니다.
{% endhint %}

## 언제 대시보드에 보이나요

`202 Accepted` 는 **접수했다는 확인**이지 대시보드에 반영됐다는 뜻이 아니에요. 보내신 데이터는 접수 → 검증 → 적재 → 데이터 갱신 순서를 거친 뒤에 화면에 나타납니다.

* 전송 직후에 대시보드가 그대로여도 정상이에요.
* 반영은 **데이터 갱신** 시점에 이뤄집니다. 바로 확인하고 싶으시면 **\[데이터 연결] → \[API 직접 적재]** 목록에서 해당 소스의 **갱신**을 눌러 주세요.
* 갱신을 마쳤는데도 보이지 않는다면, 아래 「배치 현황 보는 방법」의 **거부** 건수를 확인해 주세요. 다만 그 칸도 검증 전에는 비어 있습니다.

## 배치 현황 보는 방법

**\[데이터 연결] → \[API 직접 적재]** 화면의 **배치 현황** 표에 전송하신 배치가 최신순으로 쌓입니다. 배치 ID·연결 ID·데이터 소스·카테고리·수신 시각은 전송 직후 바로 보여요.

{% hint style="warning" %}
**통과·거부 건수는 전송 직후에는 `-` 로 비어 있습니다.** 이 칸은 검증이 끝나야 채워지고, 검증은 데이터 갱신 주기를 따라갑니다. **보통 다음 날 갱신 이후**에 숫자가 들어와요. `-` 는 실패가 아니라 **아직 검증 전**이라는 뜻이며, `0` 과는 다릅니다. 바로 숫자를 보고 싶으시면 해당 소스의 **갱신**을 직접 눌러 주세요.
{% endhint %}

| 칸  | 값     | 의미                                   |
| -- | ----- | ------------------------------------ |
| 상태 | 검증 대기 | 접수는 됐고 아직 검증 전이에요. 통과·거부는 `-` 입니다.   |
| 상태 | 검증 완료 | 검증까지 끝나 적재 대상이 된 배치예요.               |
| 상태 | 검증 실패 | 검증에서 실패해 적재되지 않았어요.                  |
| 통과 | 숫자    | 받아들인 레코드 수.                          |
| 거부 | 숫자    | 형식이 맞지 않아 거부된 레코드 수. 이 건수는 적재되지 않아요. |

* 표에는 최근 100건까지 표시됩니다.
* 거부된 레코드가 **어떤 레코드였는지**는 화면에 표시되지 않아요. 원인 확인이 필요하시면 아래 문의처로 배치 ID 와 함께 알려 주세요.

## 전송한 데이터를 대시보드에서 빼는 방법

**해당 소스를 삭제하면**, 그 소스로 보낸 데이터가 다음 데이터 갱신부터 대시보드에서 빠집니다. **\[데이터 연결] → \[API 직접 적재]** 목록에서 해당 소스 행의 **삭제** 로 진행해 주세요.

* **연결과 전송 주소(URL)는 그대로 유지됩니다.** API 키도 그대로예요.
* 같은 연결에 소스를 다시 추가할 수 있어요. 다시 추가하면 **`Laplace-Data-Source-Id` 만 새 값으로 바뀝니다.** 전송 주소는 바뀌지 않으니, 보내시는 쪽에서 이 헤더 값만 교체해 주세요.
* 빼신 데이터를 되돌리려면 같은 데이터를 다시 전송하시면 됩니다.

{% hint style="warning" %}
소스를 유지한 채 **일부 데이터만 골라서 지우는 기능은 현재 제공하지 않아요.** 기간이나 배치 단위로 선택 삭제가 필요하시면 아래 문의처로 알려 주세요.
{% endhint %}

## 예시

```bash
gzip -c batch.ndjson | curl -X POST \
  "https://api.gateway.laplacetec.com/v1/ingest/<ingest_key>" \
  -H "Laplace-Api-Key: <api_key>" \
  -H "Laplace-Data-Source-Id: <data_source_id>" \
  -H "Idempotency-Key: <batch-1-key>" \
  -H "Content-Encoding: gzip" \
  -H "Content-Type: application/x-ndjson" \
  --data-binary @-
```

Push API 연결에 어려움이 있으실 경우, 하단의 문의하기 혹은 홈페이지의 채팅 상담을 통해 문의해 주세요.\
담당 매니저가 연동에 도움을 드리도록 하겠습니다.

> 💬 [채팅으로 문의하기](https://laplacetec.channel.io/lounge)
>
> 💬 [홈페이지에서 문의하기](https://www.analytics.laplacetec.com/contact)

**이메일 문의:** [**product@laplacetec.com**](mailto:product@laplacetec.com)
