# 사용자 속성

{% hint style="info" %}
HTTP API는 서버 환경에서만 사용할 수 있습니다.
{% endhint %}

사용자 속성 API를 사용하면 이벤트를 전송하지 않고 사용자의 속성을 업데이트 할 수 있습니다.

업데이트된 속성은 소급적용되지 않으며, 업데이트 이후에 발생된 이벤트에만 적용됩니다.

SDK 키를 통해 인증을 진행합니다.

* SDK 키를 아래와 같이 HTTP 헤더에 추가해주세요.
* SDK 키는 핵클 대시보드 내 [SDK 연동 정보](https://dashboard.hackle.io/config/sdk-setting)에서 확인하실 수 있습니다.

```http
X-HACKLE-API-KEY: {YOUR_SERVER_SDK_KEY}
```

***

## 사용자 일반 속성

### Request

```http
POST https://api.hackle.io/v1/properties
```

### Request Body

| Field      | Type              | Required | Description                           |
| ---------- | ----------------- | -------- | ------------------------------------- |
| userId     | string            | X        | 사용자 ID *(deviceId 가 없는 경우 필수입니다)*     |
| deviceId   | string            | X        | 디바이스 ID *(userId 가 없는 경우 필수입니다)*      |
| operations | Operations Object | O        | 사용자 속성 업데이트를 위한 정보를 나타내는 object 입니다. |

**Operations Object**

| Field    | Type   | Required | Description                                                |
| -------- | ------ | -------- | ---------------------------------------------------------- |
| $set     | object | X        | 속성의 값을 설정합니다. 설정하고자 하는 속성의 키-값의 object 입니다.                |
| $setOnce | object | X        | 값이 아직 설정되지 않은 경우에만 값을 설정합니다. 설정하고자 하는 속성의 키-값의 object 입니다. |
| $unset   | object | X        | 속성을 제거합니다. 제거하고자 하는 속성의 키-값의 object 입니다.                   |

#### Request Body Example

```shell
curl -i -X POST \
  'https://api.hackle.io/v1/properties' \
  -H 'X-HACKLE-API-KEY: YOUR_SDK_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "userId": "19285035",
    "deviceId": "ae2182e0",
    "operations": {
      "$set": {
        "age": 42,
        "grade": "GOLD"
      },
      "$setOnce": {
        "sign_up_date": "2020-01-01"
      },
      "$unset": {
        "membership_type": "-"
      }
    }
  }'
```

### Response

#### 200 OK

성공적인 요청인 경우 200 응답 상태를 반환합니다.

#### 400 Bad Request

유효하지 않은 요청 정보인 경우 400 상태를 반환합니다.

**401 Unauthorized**

`X-HACKLE-API-KEY` 헤더값이 없거나 유효하지 않은 SDK 키인 경우 401 상태를 반환합니다.

***

## 사용자 휴대폰 번호 속성 업데이트

### Request

```http
POST https://api.hackle.io/v1/properties/phone-numbers
```

### Request Body

| Field       | Type   | Required | Description                                                                         |
| ----------- | ------ | -------- | ----------------------------------------------------------------------------------- |
| userId      | string | O        | 사용자 ID                                                                              |
| phoneNumber | string | O        | 사용자 휴대폰 번호 ([E.164](https://en.wikipedia.org/wiki/E.164) 포멧) ex) +821012345678 (권장) |

#### Request Body Example

```shell
curl -i -X POST \
  'https://api.hackle.io/v1/properties/phone-numbers' \
  -H 'X-HACKLE-API-KEY: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "userId": "19285035",
    "phoneNumber": "+821012345678"
  }'
```

### Response

#### 200 OK

성공적인 요청인 경우 200 응답 상태를 반환합니다.

#### 400 Bad Request

유효하지 않은 요청 정보인 경우 400 상태를 반환합니다.

#### 401 Unauthorized

`X-HACKLE-API-KEY` 헤더값이 없거나 유효하지 않은 SDK 키인 경우 401 상태를 반환합니다.

***

## 사용자 휴대폰 번호 속성 삭제

### Request

```http
DELETE https://api.hackle.io/v1/properties/phone-numbers
```

### Request Parameter

| Field  | Type   | Required | Description |
| ------ | ------ | -------- | ----------- |
| userId | string | O        | 사용자 ID      |

#### Request Body Example

```shell
curl -i -X DELETE \
  'https://api.hackle.io/v1/properties/phone-numbers?userId=targetUserId' \
  -H 'X-HACKLE-API-KEY: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' 
```

### Response

#### 200 OK

성공적인 요청인 경우 200 응답 상태를 반환합니다.

#### 400 Bad Request

유효하지 않은 요청 정보인 경우 400 상태를 반환합니다.

#### 401 Unauthorized

`X-HACKLE-API-KEY` 헤더값이 없거나 유효하지 않은 SDK 키인 경우 401 상태를 반환합니다.

***

## 푸시메시지 수신동의 사용자 속성

### Request

```http
POST https://api.hackle.io/v1/push-subscriptions
```

### Request Body

| Field                         | Type   | Required | Description                                                         |
| ----------------------------- | ------ | -------- | ------------------------------------------------------------------- |
| userId                        | string | X        | 사용자 ID (deviceId 가 없는 경우 필수입니다)                                     |
| deviceId                      | string | X        | 디바이스 ID (userId 가 없는 경우 필수입니다)                                      |
| marketingSubscriptionStatus   | String | X        | 마케팅 메시지 수신동의 상태 \* SUBSCRIBED : 수신동의 \* UNSUBSCRIBED : 수신미동의 (수신거부) |
| informationSubscriptionStatus | String | X        | 정보성 메시지 수신동의 상태 \* SUBSCRIBED : 수신동의 \* UNSUBSCRIBED : 수신미동의 (수신거부) |

#### Request Body Example

```shell
curl -i -X POST \
  'https://api.hackle.io/v1/push-subscriptions' \
  -H 'X-HACKLE-API-KEY: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "userId": "19285035",
    "deviceId": null,
    "marketingSubscriptionStatus": "UNSUBSCRIBED",
    "informationSubscriptionStatus" : "SUBSCRIBED"
 }'
```

### Response

#### 200 OK

성공적인 요청인 경우 200 응답 상태를 반환합니다.

#### 400 Bad Request

유효하지 않은 요청 정보인 경우 400 상태를 반환합니다.

#### 401 Unauthorized

`X-HACKLE-API-KEY` 헤더값이 없거나 유효하지 않은 SDK 키인 경우 401 상태를 반환합니다

***

## 카카오 메시지 수신동의 사용자 속성

### Request

```http
POST https://api.hackle.io/v1/kakao-subscriptions
```

### Request Body

| Field                         | Type   | Required | Description                                                         |
| ----------------------------- | ------ | -------- | ------------------------------------------------------------------- |
| userId                        | string | O        | 사용자 ID                                                              |
| marketingSubscriptionStatus   | String | X        | 마케팅 메시지 수신동의 상태 \* SUBSCRIBED : 수신동의 \* UNSUBSCRIBED : 수신미동의 (수신거부) |
| informationSubscriptionStatus | String | X        | 정보성 메시지 수신동의 상태 \* SUBSCRIBED : 수신동의 \* UNSUBSCRIBED : 수신미동의 (수신거부) |

#### Request Body Example

```shell
curl -i -X POST \
  'https://api.hackle.io/v1/kakao-subscriptions' \
  -H 'X-HACKLE-API-KEY: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "userId": "19285035",
    "marketingSubscriptionStatus": "UNSUBSCRIBED",
    "informationSubscriptionStatus" : "SUBSCRIBED"
 }'
```

### Response

#### 200 OK

성공적인 요청인 경우 200 응답 상태를 반환합니다.

#### 400 Bad Request

유효하지 않은 요청 정보인 경우 400 상태를 반환합니다.

#### 401 Unauthorized

`X-HACKLE-API-KEY` 헤더값이 없거나 유효하지 않은 SDK 키인 경우 401 상태를 반환합니다

***

## 문자 메시지 수신동의 사용자 속성

### Request

```http
POST https://api.hackle.io/v1/sms-subscriptions
```

### Request Body

| Field                         | Type   | Required | Description                                                         |
| ----------------------------- | ------ | -------- | ------------------------------------------------------------------- |
| userId                        | string | O        | 사용자 ID                                                              |
| marketingSubscriptionStatus   | String | X        | 마케팅 메시지 수신동의 상태 \* SUBSCRIBED : 수신동의 \* UNSUBSCRIBED : 수신미동의 (수신거부) |
| informationSubscriptionStatus | String | X        | 정보성 메시지 수신동의 상태 \* SUBSCRIBED : 수신동의 \* UNSUBSCRIBED : 수신미동의 (수신거부) |

#### Request Body Example

```shell
curl -i -X POST \
  'https://api.hackle.io/v1/sms-subscriptions' \
  -H 'X-HACKLE-API-KEY: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "userId": "19285035",
    "marketingSubscriptionStatus": "UNSUBSCRIBED",
    "informationSubscriptionStatus" : "SUBSCRIBED"
 }'
```

### Response

#### 200 OK

성공적인 요청인 경우 200 응답 상태를 반환합니다.

#### 400 Bad Request

유효하지 않은 요청 정보인 경우 400 상태를 반환합니다.

#### 401 Unauthorized

`X-HACKLE-API-KEY` 헤더값이 없거나 유효하지 않은 SDK 키인 경우 401 상태를 반환합니다


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hackle.io/development-guide/http-api/api-properties.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
