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

# 고객 등록과 ID 대응

> 고객을 등록하고 도입사 시스템의 ID와 MeterEngine 고객 id를 대응시키는 방법을 설명합니다.

사용량 이벤트는 고객에게 붙습니다. 이벤트를 보내기 전에 청구할 고객을 MeterEngine에 등록하고, 등록 응답으로 받은 고객 id를 도입사 시스템에 저장해 둡니다.

이벤트의 `customer_id`에는 외부 고객 ID가 아니라 MeterEngine이 만든 고객 id(UUID)를 넣습니다. 외부 고객 ID(`external_id`)는 고객을 다시 찾고 같은 고객이 두 번 등록되지 않게 막는 값입니다.

| 값 | 누가 정하나 | 쓰는 곳 |
| - | - | - |
| `id` (UUID) | MeterEngine이 등록할 때 만듭니다 | 이벤트의 `customer_id`, 고객 조회와 수정, 결제 |
| `external_id` | 도입사가 정합니다(도입사 시스템의 회원 번호 등) | 등록 중복 방지, 고객 다시 찾기 |

> [!NOTE]
>
> 콘솔 '고객' 화면에는 '외부 고객 ID로 사용량을 연결'이라고 쓰여 있지만, 외부 고객 ID는 고객을 찾는 값이고 이벤트를 고객에 연결하는 값은 고객 id입니다.

## 필요 권한

| 요청 | 권한 |
| - | - |
| 고객 등록 `POST /v1/customers` | ingest |
| 고객 목록과 조회 `GET /v1/customers`, `GET /v1/customers/{id}` | read |
| 고객 수정, 보관, 복원 | admin |

권한의 뜻과 포함 관계는 [API 권한](https://docs.meterengine.com/authentication/scopes.md)을 보세요.

## 고객 등록하기

**1. 업무 환경과 키를 확인한다**

연동을 시험할 때는 테스트 환경에서 발급한 키(`me_test_`로 시작)를 씁니다. 고객은 업무 환경마다 따로 등록되므로 테스트 환경에 등록한 고객은 실제 환경에 없습니다. 실제 환경으로 넘어갈 때 고객을 다시 등록합니다. 자세한 내용은 [업무 환경](https://docs.meterengine.com/concepts/environments.md)을 보세요.

**2. external\_id를 넣어 등록한다**

도입사 시스템에서 그 고객을 가리키는 고유한 값을 `external_id`에 넣어 보냅니다.

```bash curl theme={null}
curl -X POST https://meterengine.com/v1/customers \
  -H "Authorization: Bearer me_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "에이콘 주식회사",
    "external_id": "acct_1024",
    "billing_email": "billing@acorn.example"
  }'
```

```javascript Node theme={null}
const response = await fetch("https://meterengine.com/v1/customers", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.METERENGINE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "에이콘 주식회사",
    external_id: "acct_1024",
    billing_email: "billing@acorn.example",
  }),
});
const customer = await response.json();
// response.status는 새로 만들면 201, 이미 있던 고객이면 200입니다.
```

**3. 응답의 id를 저장한다**

새로 만들면 `201 Created`와 함께 고객이 돌아옵니다.

```json 201 Created theme={null}
{
  "id": "3f6c2a8e-5b1d-4c7a-9e2f-8d4b6a1c0e57",
  "name": "에이콘 주식회사",
  "billing_email": "billing@acorn.example",
  "created_at": "2026-11-05T10:00:00+09:00",
  "external_id": "acct_1024",
  "archived_at": null,
  "version": 0
}
```

`id`를 도입사 시스템에 `external_id`와 함께 저장합니다. 이 값이 이벤트의 `customer_id`가 됩니다.

**4. 이벤트에 id를 쓴다**

저장한 `id`를 `customer_id`에 넣어 이벤트를 보냅니다. 방법은 [사용량 이벤트 보내기](https://docs.meterengine.com/integration/events.md)를 보세요.

콘솔에서도 '고객' 화면의 '고객 등록'에서 '고객명', '외부 고객 ID', '청구 이메일'을 넣고 '고객 저장'을 눌러 등록할 수 있습니다.

### 요청 본문

| 필드 | 필수 | 형식 |
| - | - | - |
| `name` | 예 | 공백이 아닌 문자열, 255자까지 |
| `external_id` | 아니오 | 1자에서 255자. 업무 환경 안에서 고유합니다 |
| `billing_email` | 아니오 | 이메일 형식(`@` 뒤 도메인에 점이 있어야 합니다), 254자까지. 없으면 빼거나 `null`로 보냅니다 |

`billing_email`은 저장만 됩니다. MeterEngine은 메일을 보내지 않으니 청구 안내는 도입사가 직접 전달합니다. [소개](https://docs.meterengine.com/index.md)를 보세요.

### 응답

**id** `string (UUID)`

MeterEngine 고객 id. 이벤트의 `customer_id`에 넣는 값입니다.

**name** `string | null`

고객명.

**billing\_email** `string | null`

저장한 청구 이메일. 등록하지 않았으면 `null`입니다.

**created\_at** `string (date-time) | null`

등록 시각.

**external\_id** `string | null`

등록할 때 보낸 외부 고객 ID. 보내지 않았으면 `null`입니다.

**archived\_at** `string (date-time) | null`

보관 시각. 보관하지 않은 고객이면 `null`입니다.

**version** `integer`

고객 정보의 버전. 수정할 때 `If-Match`에 씁니다.

| 상태 | code | 뜻 |
| - | - | - |
| 201 | | 새 고객을 만들었습니다 |
| 200 | | 같은 `external_id`의 고객이 이미 있어 그 고객을 돌려줍니다. 이름과 이메일은 바뀌지 않습니다 |
| 400 | `validation_error` | 필드 형식이 틀렸습니다. `errors`에 틀린 필드가 있습니다 |
| 409 | `customer_archived` | 같은 `external_id`의 고객이 보관되어 있습니다 |
| 409 | `idempotency_conflict` | 같은 `Idempotency-Key`를 다른 본문에 썼습니다 |

## 같은 external\_id로 다시 보낼 때

같은 업무 환경에서 같은 `external_id`로 `POST /v1/customers`를 다시 보내면 새 고객을 만들지 않고 기존 고객을 `200 OK`로 돌려줍니다. 응답을 받지 못해 다시 보내도 고객이 하나만 생기므로, 등록 요청은 `external_id`를 넣어 보내는 것을 기본으로 하세요.

다시 보낸 요청의 `name`, `billing_email`은 저장된 값을 바꾸지 않습니다. 형식 검사는 그대로 하므로 `name`은 빼지 말고 보냅니다. 고객 정보를 바꾸려면 admin 권한 키로 `PUT /v1/customers/{id}`를 부르거나 콘솔 고객 상세 화면의 '고객 정보 수정'을 씁니다. `PUT`은 보낸 값으로 통째로 바꾸므로 `billing_email`을 빼고 보내면 저장된 청구 이메일이 지워집니다.

키에 read 권한이 없으면(ingest만 있으면) `200` 응답에는 `id`, `external_id`, `version`만 채워지고 나머지는 `null`입니다. `id`는 항상 들어 있으니 저장에는 지장이 없습니다.

```json 200 OK (read 권한이 없는 키) theme={null}
{
  "id": "3f6c2a8e-5b1d-4c7a-9e2f-8d4b6a1c0e57",
  "name": null,
  "billing_email": null,
  "created_at": null,
  "external_id": "acct_1024",
  "archived_at": null,
  "version": 0
}
```

> [!WARNING]
>
> `external_id`를 빼고 등록하면 보낼 때마다 새 고객이 만들어집니다. 응답을 받지 못해 같은 요청을 다시 보내면 같은 고객이 두 명 생깁니다. `external_id`를 넣을 수 없다면 `Idempotency-Key` 헤더를 붙여 보내세요. 같은 키와 같은 본문을 다시 보내면 처음 응답을 그대로 돌려줍니다. 자세한 규칙은 [멱등 규칙](https://docs.meterengine.com/api-basics/idempotency.md)을 보세요.

## 고객 id를 잃었을 때

저장해 둔 고객 id를 잃었으면 다음 중 하나로 다시 찾습니다.

> [accordion] 같은 external\_id로 다시 등록한다 (ingest 권한)
>
> `POST /v1/customers`를 같은 `external_id`로 다시 보내면 기존 고객이 `200`으로 돌아오고 `id`가 들어 있습니다. 이벤트를 보내는 ingest 키 하나로 할 수 있습니다.

> [accordion] external\_id로 조회한다 (read 권한)
>
> ```bash theme={null}
> curl "https://meterengine.com/v1/customers?external_id=acct_1024" \
>   -H "Authorization: Bearer me_test_xxxxxxxx"
> ```
>
> ```json 200 OK theme={null}
> {
>   "customers": [
>     {
>       "id": "3f6c2a8e-5b1d-4c7a-9e2f-8d4b6a1c0e57",
>       "name": "에이콘 주식회사",
>       "billing_email": "billing@acorn.example",
>       "created_at": "2026-11-05T10:00:00+09:00",
>       "external_id": "acct_1024",
>       "archived_at": null,
>       "version": 0
>     }
>   ]
> }
> ```
>
> 기본으로는 보관하지 않은 고객만 나옵니다. 보관한 고객까지 찾으려면 `status=all`을 붙입니다(`active`, `archived`, `all`). 없으면 `customers`가 빈 배열입니다.

> [accordion] 콘솔에서 확인한다
>
> 콘솔 '고객' 화면의 목록에는 고객 id 열이 없습니다. 고객 이름을 눌러 고객 상세 화면을 열면 주소가 `/customers/<고객 id>?month=...` 형태이고, `/customers/` 뒤부터 `?` 앞까지가 고객 id입니다.

## 보관한 고객

고객을 보관하면 그 고객의 새 이벤트와 같은 `external_id`의 등록이 `409 customer_archived`로 거절됩니다. 지난 이벤트와 청구, 결제 기록은 남습니다. 다시 쓰려면 admin 권한 키로 `POST /v1/customers/{id}/restorations`를 부르거나 콘솔 고객 상세 화면의 '고객 복원'을 누릅니다. 보관과 복원 규칙은 [바꾸기, 보관, 복원](https://docs.meterengine.com/pricing/changes-and-archiving.md)을 보세요.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.