> For the complete documentation index, see [llms.txt](https://helps.ptengine.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://helps.ptengine.com/developer/user-data-upload-api.md).

# ユーザープロパティアップロードAPI

Ptengine APIを使用することで、ユーザープロパティ情報を一括でPtengineにアップロードし、後続のユーザーセグメント分析などに活用することができます。

本APIはRESTアーキテクチャに基づいて構築されており、JSON形式のリクエストボディを受け入れ、JSONエンコードされたレスポンスを返します。

***

## 1. 認証

### APIキーの取得

Ptengineの「Integration（連携）」ページにてAPIキーを取得または新規作成してください。

{% hint style="warning" %}
APIキーはプロジェクトレベルであり、各プロジェクトごとに個別に作成する必要があります。
{% endhint %}

### APIキーの保護

APIキーは機密情報です。ブラウザやモバイルアプリなどのクライアントコード内で公開しないでください。本番環境のリクエストは、組織のバックエンドサーバーを経由してルーティングし、**環境変数**や**キーマネージメントサービス**から安全に読み込むことを推奨します。

すべてのAPIリクエストは、HTTPヘッダーにAPIキーを含める必要があります：

```
Authorization: Bearer PTENGINE_API_KEY
```

***

## 2. APIの仕様

| 項目      | 内容                                          |
| ------- | ------------------------------------------- |
| API URL | `https://api.ptengine.com/v1/user/profiles` |
| プロトコル   | HTTPS                                       |
| リクエスト方法 | POST                                        |
| データ形式   | JSON                                        |

1回のリクエストで最大100人のユーザーと属性データを同時にアップロードできます。

***

## 3. リクエストボディ

リクエストボディには以下2つのフィールドを含めます：

| フィールド名       | データ型      | 必須 | 説明                                                               | 制限                       |
| ------------ | --------- | -- | ---------------------------------------------------------------- | ------------------------ |
| `field_name` | String\[] | はい | ユーザープロパティのキー名の配列。`user_id` を必ず含める必要があります                         | フィールド数は最大50個、各属性名は最大50文字 |
| `values`     | Array\[]  | はい | ユーザープロパティの値を含む二次元配列。順序は `field_name` に対応させてください。空の値は `""` で表現します | 最大100ユーザー、各属性値は最大128文字   |

***

## 4. 更新ポリシー

各リクエストには `user_id`（ユーザーの一意の識別子）を含める必要があります。Ptengineは `user_id` を使用してユーザーの存在状態を確認し、以下のルールに従って処理します：

| ユーザーの状態 | 属性の状態 | 更新ポリシー              |
| ------- | ----- | ------------------- |
| 存在する    | 存在する  | 既存の属性を更新します         |
| 存在する    | 存在しない | 新規でユーザーの属性を作成します    |
| 存在しない   | /     | 新規でユーザー及びその属性を作成します |

***

## 5. リクエスト例

以下のようなユーザープロパティをアップロードしたいとします：

| user\_id | watch\_conan | watch\_attack\_on\_titan |
| -------- | ------------ | ------------------------ |
| abcd123  | yes          | no                       |
| abcd456  | yes          | yes                      |
| abcd789  | no           | no                       |

リクエストボディは次のようになります：

```json
{
  "field_name": [
    "user_id",
    "watch_conan",
    "watch_attack_on_titan"
  ],
  "values": [
    ["abcd123", "yes", "no"],
    ["abcd456", "yes", "yes"],
    ["abcd789", "no", "no"]
  ]
}
```

{% hint style="info" %}
`values` の順序と `field_name` の順序が一致している必要があります。
{% endhint %}

***

## 6. 各言語でのコード例

リクエストする前に、`<API_KEY>` をご自身のAPIキーに置き換えてください。

### Python

```python
import requests
import json

url = "https://api.ptengine.com/v1/user/profiles"

payload = json.dumps({
  "field_name": [
    "user_id",
    "watch_conan",
    "watch_attack_on_titan"
  ],
  "values": [
    ["abcd123", "yes", "no"],
    ["abcd456", "yes", "yes"],
    ["abcd789", "no", "no"]
  ]
})
headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Bearer <API_KEY>'
}

response = requests.post(url, headers=headers, data=payload)
print(response.json())
```

### Node.js

```javascript
const axios = require('axios');
let data = JSON.stringify({
  "field_name": [
    "user_id",
    "watch_conan",
    "watch_attack_on_titan"
  ],
  "values": [
    ["abcd123", "yes", "no"],
    ["abcd456", "yes", "yes"],
    ["abcd789", "no", "no"]
  ]
});

let config = {
  method: 'post',
  url: 'https://api.ptengine.com/v1/user/profiles',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer <API_KEY>'
  },
  data: data
};

axios(config)
  .then(response => console.log(response.data))
  .catch(error => console.log(error));
```

### PHP

```php
<?php
$client = new Client();
$headers = [
  'Content-Type' => 'application/json',
  'Authorization' => 'Bearer <API_KEY>'
];
$body = '{
  "field_name": ["user_id", "watch_conan", "watch_attack_on_titan"],
  "values": [
    ["abcd123", "yes", "no"],
    ["abcd456", "yes", "yes"],
    ["abcd789", "no", "no"]
  ]
}';
$request = new Request('POST', 'https://api.ptengine.com/v1/user/profiles', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
```

### Java

```java
OkHttpClient client = new OkHttpClient().newBuilder().build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,
  "{\"field_name\":[\"user_id\",\"watch_conan\",\"watch_attack_on_titan\"],"
  + "\"values\":[[\"abcd123\",\"yes\",\"no\"],"
  + "[\"abcd456\",\"yes\",\"yes\"],"
  + "[\"abcd789\",\"no\",\"no\"]]}");
Request request = new Request.Builder()
  .url("https://api.ptengine.com/v1/user/profiles")
  .method("POST", body)
  .addHeader("Content-Type", "application/json")
  .addHeader("Authorization", "Bearer <API_KEY>")
  .build();
Response response = client.newCall(request).execute();
```

### Go

```go
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {
  url := "https://api.ptengine.com/v1/user/profiles"
  payload := strings.NewReader(`{
    "field_name": ["user_id", "watch_conan", "watch_attack_on_titan"],
    "values": [
      ["abcd123", "yes", "no"],
      ["abcd456", "yes", "yes"],
      ["abcd789", "no", "no"]
    ]
  }`)

  req, _ := http.NewRequest("POST", url, payload)
  req.Header.Add("Content-Type", "application/json")
  req.Header.Add("Authorization", "Bearer <API_KEY>")

  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)
  fmt.Println(string(body))
}
```

***

## 7. レスポンス

### 成功

HTTPステータスコード `200 OK`

```json
{
  "msg": "Success",
  "timestamp": 1684155980
}
```

### 失敗

HTTPステータスコードはエラータイプによって異なります。

```json
{
  "msg": "The reason for the request failure",
  "timestamp": 1684155980
}
```

### ステータスコード一覧

| HTTP Status        | 説明                                                                           |
| ------------------ | ---------------------------------------------------------------------------- |
| 200 (OK)           | リクエストは成功しています                                                                |
| 400 (Bad Request)  | リクエストは受け付けられません。必要なパラメータが不足している可能性があります（例：`field_name` に `user_id` が含まれていない） |
| 401 (Unauthorized) | APIキーが無効または正しくありません                                                          |
| 403 (Forbidden)    | APIキーにはこのリクエストを実行するための適切な権限がありません                                            |
| 404 (Not Found)    | リクエストされたリソースが存在しないか、URLが間違っています                                              |
| 500/502/503/504    | Ptengineサーバーで問題が発生しました                                                       |

***

## 8. 大量データのアップロード

1回のリクエストで最大100ユーザーまでアップロード可能です。100人を超えるユーザーがいる場合は、100件ずつに分けて複数回送信してください。

例えば、600人のユーザーデータをアップロードする場合は、100人ずつ6回のリクエストに分割して送信します。
