> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/api/api-reference/zu-zhi-he-cheng-yuan.md).

# 組織與成員

### 帳號註冊 <a href="#auth-registration-create" id="auth-registration-create"></a>

POST `/api/v1/auth/registration/`

#### 請求內容

**請求參數**

| 欄位            | 類型                         | 必填 | 說明 |
| ------------- | -------------------------- | -- | -- |
| email         | string (email)             | 是  |    |
| password1     | string                     | 是  |    |
| password2     | string                     | 是  |    |
| name          | string                     | 是  |    |
| company       | string                     | 是  |    |
| referralCode  | string                     | 否  |    |
| authSource    | object (含 2 個屬性: id, name) | 否  |    |
| authSource.id | string (uuid)              | 是  |    |

**請求結構範例**

```typescript
{
  "email": string (email)
  "password1": string
  "password2": string
  "name": string
  "company": string
  "referralCode"?: string // 非必填
  "authSource"?:  // 非必填
  {
    "id": string (uuid)
  }
}
```

**請求範例值**

```json
{
  "email": "user@example.com",
  "password1": "範例字串",
  "password2": "範例字串",
  "name": "範例名稱",
  "company": "範例字串",
  "referralCode": "範例字串",
  "authSource": {
    "id": "550e8400-e29b-41d4-a716-446655440000"
  }
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/auth/registration/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password1": "範例字串",
    "password2": "範例字串",
    "name": "範例名稱",
    "company": "範例字串",
    "referralCode": "範例字串",
    "authSource": {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "email": "user@example.com",
    "password1": "範例字串",
    "password2": "範例字串",
    "name": "範例名稱",
    "company": "範例字串",
    "referralCode": "範例字串",
    "authSource": {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  };

axios.post("https://api.maiagent.ai/api/v1/auth/registration/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/auth/registration/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "email": "user@example.com",
    "password1": "範例字串",
    "password2": "範例字串",
    "name": "範例名稱",
    "company": "範例字串",
    "referralCode": "範例字串",
    "authSource": {
        "id": "550e8400-e29b-41d4-a716-446655440000"
    }
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/auth/registration/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'email' => 'user@example.com',
            'password1' => '範例字串',
            'password2' => '範例字串',
            'name' => '範例名稱',
            'company' => '範例字串',
            'referralCode' => '範例字串',
            'authSource' => [
                'id' => '550e8400-e29b-41d4-a716-446655440000'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "email": string (email)
  "password1": string
  "password2": string
  "name": string
  "company": string
  "referralCode"?: string // 非必填
  "authSource"?:  // 非必填
  {
    "id": string (uuid)
    "name": string
  }
}
```

**回應範例值**

```json
{
  "email": "response@example.com",
  "password1": "回應字串",
  "password2": "回應字串",
  "name": "回應字串",
  "company": "回應字串",
  "referralCode": "回應字串",
  "authSource": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應字串"
  }
}
```

***

### 更換密碼 <a href="#auth-password-change-create" id="auth-password-change-create"></a>

POST `/api/v1/auth/password/change/`

#### 請求內容

**請求參數**

| 欄位           | 類型     | 必填 | 說明 |
| ------------ | ------ | -- | -- |
| oldPassword  | string | 是  |    |
| newPassword1 | string | 是  |    |
| newPassword2 | string | 是  |    |

**請求結構範例**

```typescript
{
  "oldPassword": string
  "newPassword1": string
  "newPassword2": string
}
```

**請求範例值**

```json
{
  "oldPassword": "範例字串",
  "newPassword1": "範例字串",
  "newPassword2": "範例字串"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/auth/password/change/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "oldPassword": "範例字串",
    "newPassword1": "範例字串",
    "newPassword2": "範例字串"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "oldPassword": "範例字串",
    "newPassword1": "範例字串",
    "newPassword2": "範例字串"
  };

axios.post("https://api.maiagent.ai/api/v1/auth/password/change/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/auth/password/change/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "oldPassword": "範例字串",
    "newPassword1": "範例字串",
    "newPassword2": "範例字串"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/auth/password/change/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'oldPassword' => '範例字串',
            'newPassword1' => '範例字串',
            'newPassword2' => '範例字串'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "detail": string
}
```

**回應範例值**

```json
{
  "detail": "回應字串"
}
```

***

### 建立新組織 <a href="#organizations-create" id="organizations-create"></a>

POST `/api/v1/organizations/`

#### 請求內容

**請求參數**

| 欄位            | 類型              | 必填 | 說明                   |
| ------------- | --------------- | -- | -------------------- |
| name          | string          | 是  | 組織名稱                 |
| compact\_logo | string (binary) | 否  | 簡潔版 Logo（選填，僅企業方案可用） |
| full\_logo    | string (binary) | 否  | 完整版 Logo（選填，僅企業方案可用） |

**請求結構範例**

```typescript
{
  "name": string // 組織名稱
  "compact_logo"?: string (binary) // 簡潔版 Logo（選填，僅企業方案可用） (非必填)
  "full_logo"?: string (binary) // 完整版 Logo（選填，僅企業方案可用） (非必填)
}
```

**請求範例值**

```json
{
  "name": "My Organization"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/organizations/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Organization"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "name": "My Organization"
  };

axios.post("https://api.maiagent.ai/api/v1/organizations/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "name": "My Organization"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/organizations/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'name' => 'My Organization'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "createdAt": string (timestamp)
  "compactLogo"?: string (uri) // 非必填
  "fullLogo"?: string (uri) // 非必填
  "themePrimaryColor"?: // 可能有不同的類型 (非必填)
  string // UI 主題色，用於按鈕、連結等元素的顏色（HEX 格式，如 #0960bd）；留空表示未設定，前端退階使用系統品牌主色 (非必填)
  "usageStatistics": object
  "organizationPlan": object
  "creditWallet": object // Return credit wallet with ID only.
  "maigptInboxId": string (uuid)
  "canUseCustomElasticsearch": boolean // Allow this organization to configure custom Elasticsearch endpoints for knowledge bases.
  "canUseVoiceAgent": boolean // Allow this organization to use voice agent features.
  "canUseMeetingRecords": boolean // Allow this organization to use meeting records features.
  "canUseCallCenter": boolean // Allow this organization to use call center features.
  "canUseHookSystem": boolean // Manual override to grant this organization the hook system regardless of plan. Enterprise-plan organizations get access automatically without this flag. Layered under the global Config.hook_system_enabled switch: it must also be enabled.
  "canUseAiGateway": boolean // Allow this organization to call the OpenAI-compatible `/api/v1/chat/completions` Gateway. On by default for license installs, otherwise off until a platform admin enables it.
  "canUseGroupAssistant": boolean // Allow this organization to use the personal secretary (its LINE group features). Off by default; the organization admin still switches the assistant on in Admin.
  "canUseAgentTeams": boolean // Read-only projection of the platform-wide Agent Teams switch (Config.enable_agent_teams). Not a per-organization flag; member-level access is still governed by RBAC.
  "canUseFileLibrary": boolean // Allow this organization to use the file library.
  "canUseFileOnlineEditing": boolean // Enable online editing in the file library (P7): the text editor and upload-new-version entries. Requires can_use_file_library to also be on.
  "canUseOfficeOnlineEditing": boolean // Enable Office (xlsx/docx/pptx) online editing in the file library (P7 S9). Requires can_use_file_online_editing to also be on.
  "canUseRolePermissionGovernance": boolean // Always true: batch role permission settings and the effective permissions view are available to every organization. Kept for clients that still read it; access is governed by organization_overview_access.
  "enableAgentMemory": boolean // Enable persistent cross-conversation memory for agents in this organization. When off, agents use only in-session memory. On by default on SaaS; license installs remain opt-in. Members can still turn it off for themselves in Profile > AI Memory.
  "hideChinaModels"?: boolean // When on, platform models whose developer is based in China (including ones added later) cannot be used in this organization: model menus, assistants, the API and AI Gateway exclude them, and live transcription lists China-developed speech engines as unavailable. Off by default; turn it on for public-sector or other organizations that must not use them. (非必填)
  "autoActivateNewChatbotChannels"?: boolean // Initial state of the web chat and API channels of a new chatbot whose creator did not set them (duplicates, templates and API calls without the values included). When on, they start active; when off (the platform default), they start inactive until a member turns them on. The creator can still override both channels in the New Chatbot dialog or the create API. The backstage (admin) channel is always active. Changing this does not affect existing chatbots. (非必填)
  "gatewayServiceFeePercent": string (decimal) // Markup applied on top of the token price when billing MaiAgent-managed models called through the AI Gateway (/v1/chat/completions and /v1/embeddings). Managed gateway markup only; the organization's own models (BYOK / self-hosted) are billed via the AI Gateway traffic fee percent instead.
  "gatewayTrafficFeePercent": string (decimal) // Pass-through fee for calls that run on this organization's own AI Gateway models (BYOK / self-hosted): charged as the call's total tokens (input, output, and prompt-cache) x this percent in credits, with no LLM token pricing. Adjustable per organization; changes apply to new calls only.
  "platformProcessingFeePercent": string (decimal) // Surcharge on every credit consumption of this organization, billed as a separate "Platform Processing Fee" line equal to the consumed credits x this percent. 0 disables the fee. Applies to new consumption only; the percent is shown read-only on the customer pricing page.
  "platformProcessingFeeEnabled": boolean // Whether new consumption of this organization accrues the platform processing fee. The percent is exposed read-only as platform_processing_fee_percent.
  "isTrial": boolean // 是否為試用期。判定邏輯：組織只有一個試用方案且目前有效
  "expirationDays": integer // 已過期天數。正數=已過期天數，null=尚未到期或永久方案
  "showTrialBanner": boolean // 控制前端是否顯示試用/免費方案橫幅
  "agentScheduleMinIntervalSeconds": integer // 排程最小執行間隔（秒），平台設定；建立／編輯排程時前端以此提示下限，實際檢查仍在排程 API
  "noActivePlanDays": integer // Consecutive days without an active paid plan. null when cleanup is disabled.
  "cleanupRemainingDays": integer // Days remaining before organization data is permanently deleted. null when cleanup is disabled, org has an active paid plan, or no_active_plan_days is 0.
  "estimatedCleanupDate": string // ISO date when organization data will be permanently deleted. null when cleanup_remaining_days is null.
  "approvalStatus":  // Trial-eligibility review status. Only approved organizations can receive a trial plan when organization approval is enabled. Paid plan activation auto-approves the organization.

* `pending` - Pending Review
* `approved` - Approved
* `rejected` - Rejected
  {
  }
  "companyName"?: string // Applicant-reported company name collected at organization creation for approval review. (非必填)
  "taxId"?: // 可能有不同的類型 (非必填)
  string // Applicant-reported business tax ID (8 digits, optional). Stored as-is; not verified. (非必填)
  "contactPhone"?: string // Applicant-reported contact phone collected at organization creation for approval review. (非必填)
  "applicationMetadata"?: object // Extra applicant-reported key-value fields collected at organization creation. Lets the frontend collect additional review fields without a schema migration; the core review fields (company name, tax ID, contact phone) stay as named columns. (非必填)
  "invitationCode"?: string // 非必填
  "ipAllowlistEnabled": boolean // Restrict this organization to the source IPs listed in allowed_ip_cidrs. Layered under the global Config.ip_allowlist_enforcement_enabled switch: both must be enabled. Disabled by default so existing organizations keep unrestricted access.
  "allowedIpCidrs": string // Source IPs or CIDRs allowed to reach this organization, one per line (e.g. 203.0.113.0/24); commas also work. While the IP allowlist is enabled, an empty list rejects everything. A non-empty list whose entries are all invalid rejects everything rather than silently reverting to unrestricted, so a typo cannot quietly disable the protection. Matching uses the load-balancer-appended client IP.
  "enforceIpAllowlistOnAdminUi": boolean // Apply the allowlist to browser sessions: the admin console and its WebSocket connections. Only takes effect while ip_allowlist_enabled is on.
  "enforceIpAllowlistOnApiKey": boolean // Apply the allowlist to Open API (Api-Key) and AI Gateway (Bearer) requests. Only takes effect while ip_allowlist_enabled is on.
}
```

**回應範例值**

```json
{
  "id": "5b01e0b9-0b0e-4079-8150-d12015576d2c",
  "name": "My Organization",
  "createdAt": "1748336288000",
  "compactLogo": null,
  "fullLogo": null,
  "usageStatistics": {
    "chatbotsCount": 0,
    "countableChatbotsCount": 0,
    "exemptChatbotsByMode": {},
    "canCreateChatbot": true,
    "createChatbotLimit": 1,
    "currentMonthWordsCountTotal": 1000000,
    "currentMonthUsedWordsCountTotal": 0,
    "currentMonthUsedConversationsCountTotal": 0,
    "availableUploadFilesSizeTotal": 104857600,
    "usedUploadFileSizeTotal": 0
  },
  "organizationPlan": {
    "id": "cac825e8-cb9b-4a16-b440-4ff6b2e73911",
    "planName": "免費方案",
    "planType": "free",
    "expiredAt": null
  },
  "maigptInboxId": null,
  "canUseCustomElasticsearch": false,
  "isTrial": true,
  "expirationDays": null
}
```

***

### 新增成員至指定組織 <a href="#organizations-members-create" id="organizations-members-create"></a>

POST `/api/v1/organizations/{organizationPk}/members/`

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 請求內容

**請求參數**

| 欄位           | 類型             | 必填 | 說明 |
| ------------ | -------------- | -- | -- |
| email        | string (email) | 是  |    |
| organization | string (uuid)  | 否  |    |

**請求結構範例**

```typescript
{
  "email": string (email)
  "organization"?: string (uuid) // 非必填
}
```

**請求範例值**

```json
{
  "organization": "613c86f7-a45f-4e29-b255-29caff89de32",
  "is_owner": false
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "organization": "613c86f7-a45f-4e29-b255-29caff89de32",
    "is_owner": false
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "organization": "613c86f7-a45f-4e29-b255-29caff89de32",
    "is_owner": false
  };

axios.post("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "organization": "613c86f7-a45f-4e29-b255-29caff89de32",
    "is_owner": False
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'organization' => '613c86f7-a45f-4e29-b255-29caff89de32',
            'is_owner' => false
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "organization": string (uuid) // 組織 ID
  "is_owner": boolean // 是否為組織擁有者
}
```

**回應範例值**

```json
{
  "organization": "613c86f7-a45f-4e29-b255-29caff89de32",
  "is_owner": false
}
```

***

### 批次匯入成員 <a href="#organizations-members-bulk-import-create" id="organizations-members-bulk-import-create"></a>

POST `/api/v1/organizations/{organizationPk}/members/bulk-import/`

{% hint style="info" %}
以 `multipart/form-data` 上傳 `file`（.xlsx，`Email(required)` 欄必填、`Name` 欄選填）。單次最多 25,000 列（不含標題列），超過時整份不匯入並回 `400`，請分檔匯入；任一列 Email 空白或無效、或 Name 超過 255 字，也是整份不匯入，`400` 的 `detail` 是逐列列出錯誤的字串陣列；缺少 `Email(required)` 欄或檔案沒有任何資料列時，`detail` 是單一字串；檔案不是 .xlsx 時，錯誤放在 `file` 欄位。同一 Email 重複出現時只處理第一筆。Email 尚未加入組織的人會加入組織，計入 `added`，Name 會成為他的組織內名稱（帳號是這次才建立的，Name 也作為帳號名稱，未填時用 Email 前綴）。Email 已是成員時，依匯入者身分處理：組織擁有者匯入時，Name 與目前顯示名稱不同就更新該成員的組織內名稱（`updated`），Name 空白或相同不變更（`unchanged`），Name 不同但成員由 SCIM 同步管理時不更新（`scimSkipped`）；非擁有者匯入時維持原行為，既有成員略過、不更新名稱（`skippedExisting`）。`importerIsOwner` 標示匯入者是否為擁有者。只會更新組織內名稱，不會改既有成員的帳號名稱。`created` 維持原本意義，是新加入與既有成員的合計，等於 `added`、`updated`、`unchanged`、`scimSkipped`、`skippedExisting` 五項相加，只讀 `created` 的串接不需修改。`message` 是逐列訊息：擁有者匯入時不再出現「已在組織中」，改為「第 N 列：已更新名稱」「第 N 列：未變更」「第 N 列：SCIM 同步管理，未更新」；非擁有者匯入時維持原本的訊息。
{% endhint %}

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/bulk-import/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -F "file=@example_file.xlsx"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');
const FormData = require('form-data');

// 建立FormData對象
const formData = new FormData();
// 請用實際檔案替換
formData.append('file', /* 實際檔案物件 */, 'example_file.xlsx');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    ...formData.getHeaders()
  }
};

axios.post("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/bulk-import/", formData, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/bulk-import/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}

# 建立檔案和表單資料
files = {
    'file': ('example_file.xlsx', open('example_file.xlsx', 'rb'), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
}

response = requests.post(url, files=files, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/bulk-import/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ],
        'multipart' => [
            [
                'name' => 'file',
                'contents' => fopen('example_file.xlsx', 'r'),
                'filename' => 'example_file.xlsx'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "created": integer // 處理的總成員數量（包含新建立和已存在的）
  "added": integer // 新加入組織的成員數
  "updated": integer // 擁有者匯入時，更新組織內名稱的既有成員數
  "unchanged": integer // 擁有者匯入時，Name 空白或與目前顯示名稱相同而未變更的既有成員數
  "scimSkipped": integer // 擁有者匯入時，由 SCIM 同步管理而未更新名稱的既有成員數
  "skippedExisting": integer // 非擁有者匯入時，已在組織中而略過的成員數；擁有者匯入時為 0
  "importerIsOwner": boolean // 匯入者是否為組織擁有者
  "message"?: [ // 逐列訊息（沒有時不回傳）。擁有者匯入：「第 N 列：已更新名稱／未變更／SCIM 同步管理，未更新」；非擁有者匯入：列出已在組織中而跳過的行號和 email (非必填)
    string
  ]
}
```

**回應範例值**

```json
{
  "created": 5,
  "added": 2,
  "updated": 1,
  "unchanged": 1,
  "scimSkipped": 1,
  "skippedExisting": 0,
  "importerIsOwner": true,
  "message": [
    "第 2 列：已更新名稱",
    "第 3 列：未變更",
    "第 5 列：SCIM 同步管理，未更新"
  ]
}
```

**狀態碼: 400 - 驗證錯誤，整份檔案都不會匯入**

**回應結構範例**

```typescript
{
  "detail"?: // 可能有不同的類型 (非必填)
  array[string] // 整份不匯入的原因。字串陣列：逐列列出的錯誤（例如 Email 空白、Name 超過 255 字），或超過單次 25,000 列上限；字串：缺少必填欄位，或檔案沒有任何資料列 (非必填)
  "file"?: [ // 檔案不是 .xlsx 格式 (非必填)
    string
  ]
}
```

**回應範例值**

```json
{
  "detail": [
    "第 3 列：Email 不能為空",
    "第 5 列：Email 不能為空"
  ]
}
```

***

### 取得組織列表 <a href="#organizations-list" id="organizations-list"></a>

GET `/api/v1/organizations/`

#### 參數

| 參數名稱         | 必填 | 類型      | 說明                                             |
| ------------ | -- | ------- | ---------------------------------------------- |
| `page`       | ❌  | integer | A page number within the paginated result set. |
| `pageSize`   | ❌  | integer | Number of results to return per page.          |
| `pagination` | ❌  | string  | 是否分頁 (true/false)                              |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/?page=1&pageSize=1&pagination=example" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/?page=1&pageSize=1&pagination=example", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/?page=1&pageSize=1&pagination=example"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/?page=1&pageSize=1&pagination=example", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "id": string (uuid)
      "name": string
      "createdAt": string (timestamp)
      "memberCreatedAt": string (timestamp)
      "approvalStatus": string
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應字串",
      "createdAt": "回應字串",
      "memberCreatedAt": "回應字串",
      "approvalStatus": "回應字串"
    }
  ]
}
```

***

### 取得特定組織資訊 <a href="#organizations-retrieve" id="organizations-retrieve"></a>

GET `/api/v1/organizations/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                 |
| ---- | -- | ------ | ---------------------------------- |
| `id` | ✅  | string | A UUID string identifying this 組織. |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "createdAt": string (timestamp)
  "compactLogo"?: string (uri) // 非必填
  "fullLogo"?: string (uri) // 非必填
  "themePrimaryColor"?: // 可能有不同的類型 (非必填)
  string // UI 主題色，用於按鈕、連結等元素的顏色（HEX 格式，如 #0960bd）；留空表示未設定，前端退階使用系統品牌主色 (非必填)
  "usageStatistics": object
  "organizationPlan": object
  "creditWallet": object // Return credit wallet with ID only.
  "maigptInboxId": string (uuid)
  "canUseCustomElasticsearch": boolean // Allow this organization to configure custom Elasticsearch endpoints for knowledge bases.
  "canUseVoiceAgent": boolean // Allow this organization to use voice agent features.
  "canUseMeetingRecords": boolean // Allow this organization to use meeting records features.
  "canUseCallCenter": boolean // Allow this organization to use call center features.
  "canUseHookSystem": boolean // Manual override to grant this organization the hook system regardless of plan. Enterprise-plan organizations get access automatically without this flag. Layered under the global Config.hook_system_enabled switch: it must also be enabled.
  "canUseAiGateway": boolean // Allow this organization to call the OpenAI-compatible `/api/v1/chat/completions` Gateway. On by default for license installs, otherwise off until a platform admin enables it.
  "canUseGroupAssistant": boolean // Allow this organization to use the personal secretary (its LINE group features). Off by default; the organization admin still switches the assistant on in Admin.
  "canUseAgentTeams": boolean // Read-only projection of the platform-wide Agent Teams switch (Config.enable_agent_teams). Not a per-organization flag; member-level access is still governed by RBAC.
  "canUseFileLibrary": boolean // Allow this organization to use the file library.
  "canUseFileOnlineEditing": boolean // Enable online editing in the file library (P7): the text editor and upload-new-version entries. Requires can_use_file_library to also be on.
  "canUseOfficeOnlineEditing": boolean // Enable Office (xlsx/docx/pptx) online editing in the file library (P7 S9). Requires can_use_file_online_editing to also be on.
  "canUseRolePermissionGovernance": boolean // Always true: batch role permission settings and the effective permissions view are available to every organization. Kept for clients that still read it; access is governed by organization_overview_access.
  "enableAgentMemory": boolean // Enable persistent cross-conversation memory for agents in this organization. When off, agents use only in-session memory. On by default on SaaS; license installs remain opt-in. Members can still turn it off for themselves in Profile > AI Memory.
  "hideChinaModels"?: boolean // When on, platform models whose developer is based in China (including ones added later) cannot be used in this organization: model menus, assistants, the API and AI Gateway exclude them, and live transcription lists China-developed speech engines as unavailable. Off by default; turn it on for public-sector or other organizations that must not use them. (非必填)
  "autoActivateNewChatbotChannels"?: boolean // Initial state of the web chat and API channels of a new chatbot whose creator did not set them (duplicates, templates and API calls without the values included). When on, they start active; when off (the platform default), they start inactive until a member turns them on. The creator can still override both channels in the New Chatbot dialog or the create API. The backstage (admin) channel is always active. Changing this does not affect existing chatbots. (非必填)
  "gatewayServiceFeePercent": string (decimal) // Markup applied on top of the token price when billing MaiAgent-managed models called through the AI Gateway (/v1/chat/completions and /v1/embeddings). Managed gateway markup only; the organization's own models (BYOK / self-hosted) are billed via the AI Gateway traffic fee percent instead.
  "gatewayTrafficFeePercent": string (decimal) // Pass-through fee for calls that run on this organization's own AI Gateway models (BYOK / self-hosted): charged as the call's total tokens (input, output, and prompt-cache) x this percent in credits, with no LLM token pricing. Adjustable per organization; changes apply to new calls only.
  "platformProcessingFeePercent": string (decimal) // Surcharge on every credit consumption of this organization, billed as a separate "Platform Processing Fee" line equal to the consumed credits x this percent. 0 disables the fee. Applies to new consumption only; the percent is shown read-only on the customer pricing page.
  "platformProcessingFeeEnabled": boolean // Whether new consumption of this organization accrues the platform processing fee. The percent is exposed read-only as platform_processing_fee_percent.
  "isTrial": boolean // 是否為試用期。判定邏輯：組織只有一個試用方案且目前有效
  "expirationDays": integer // 已過期天數。正數=已過期天數，null=尚未到期或永久方案
  "showTrialBanner": boolean // 控制前端是否顯示試用/免費方案橫幅
  "agentScheduleMinIntervalSeconds": integer // 排程最小執行間隔（秒），平台設定；建立／編輯排程時前端以此提示下限，實際檢查仍在排程 API
  "noActivePlanDays": integer // Consecutive days without an active paid plan. null when cleanup is disabled.
  "cleanupRemainingDays": integer // Days remaining before organization data is permanently deleted. null when cleanup is disabled, org has an active paid plan, or no_active_plan_days is 0.
  "estimatedCleanupDate": string // ISO date when organization data will be permanently deleted. null when cleanup_remaining_days is null.
  "approvalStatus":  // Trial-eligibility review status. Only approved organizations can receive a trial plan when organization approval is enabled. Paid plan activation auto-approves the organization.

* `pending` - Pending Review
* `approved` - Approved
* `rejected` - Rejected
  {
  }
  "companyName"?: string // Applicant-reported company name collected at organization creation for approval review. (非必填)
  "taxId"?: // 可能有不同的類型 (非必填)
  string // Applicant-reported business tax ID (8 digits, optional). Stored as-is; not verified. (非必填)
  "contactPhone"?: string // Applicant-reported contact phone collected at organization creation for approval review. (非必填)
  "applicationMetadata"?: object // Extra applicant-reported key-value fields collected at organization creation. Lets the frontend collect additional review fields without a schema migration; the core review fields (company name, tax ID, contact phone) stay as named columns. (非必填)
  "invitationCode"?: string // 非必填
  "ipAllowlistEnabled": boolean // Restrict this organization to the source IPs listed in allowed_ip_cidrs. Layered under the global Config.ip_allowlist_enforcement_enabled switch: both must be enabled. Disabled by default so existing organizations keep unrestricted access.
  "allowedIpCidrs": string // Source IPs or CIDRs allowed to reach this organization, one per line (e.g. 203.0.113.0/24); commas also work. While the IP allowlist is enabled, an empty list rejects everything. A non-empty list whose entries are all invalid rejects everything rather than silently reverting to unrestricted, so a typo cannot quietly disable the protection. Matching uses the load-balancer-appended client IP.
  "enforceIpAllowlistOnAdminUi": boolean // Apply the allowlist to browser sessions: the admin console and its WebSocket connections. Only takes effect while ip_allowlist_enabled is on.
  "enforceIpAllowlistOnApiKey": boolean // Apply the allowlist to Open API (Api-Key) and AI Gateway (Bearer) requests. Only takes effect while ip_allowlist_enabled is on.
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "createdAt": "回應字串",
  "compactLogo": "https://example.com/file.jpg",
  "fullLogo": "https://example.com/file.jpg",
  "themePrimaryColor": "回應字串",
  "usageStatistics": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "organizationPlan": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "creditWallet": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "maigptInboxId": "550e8400-e29b-41d4-a716-446655440000",
  "canUseCustomElasticsearch": false,
  "canUseVoiceAgent": false,
  "canUseMeetingRecords": false,
  "canUseCallCenter": false,
  "canUseHookSystem": false,
  "canUseAiGateway": false,
  "canUseGroupAssistant": false,
  "canUseAgentTeams": false,
  "canUseFileLibrary": false,
  "canUseFileOnlineEditing": false,
  "canUseOfficeOnlineEditing": false,
  "canUseRolePermissionGovernance": false,
  "enableAgentMemory": false,
  "hideChinaModels": false,
  "autoActivateNewChatbotChannels": false,
  "gatewayServiceFeePercent": "回應字串",
  "gatewayTrafficFeePercent": "回應字串",
  "platformProcessingFeePercent": "回應字串",
  "platformProcessingFeeEnabled": false,
  "isTrial": false,
  "expirationDays": 456,
  "showTrialBanner": false,
  "agentScheduleMinIntervalSeconds": 456,
  "noActivePlanDays": 456,
  "cleanupRemainingDays": 456,
  "estimatedCleanupDate": "回應字串",
  "approvalStatus": {},
  "companyName": "回應字串",
  "taxId": "回應字串",
  "contactPhone": "回應字串",
  "applicationMetadata": null,
  "invitationCode": "回應字串",
  "ipAllowlistEnabled": false,
  "allowedIpCidrs": "回應字串",
  "enforceIpAllowlistOnAdminUi": false,
  "enforceIpAllowlistOnApiKey": false
}
```

***

### 取得當前用戶詳細資訊 <a href="#users-current-retrieve" id="users-current-retrieve"></a>

GET `/api/v1/users/current/`

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/users/current/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/users/current/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/users/current/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/users/current/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "avatar"?: string (uri) // 非必填
  "originalAvatar"?: string (uri) // 使用者上傳的頭貼原圖（長邊已限制在 2048px 內），每次編輯都從這張重裁，避免在裁切結果上再裁而累積失真。本功能上線前的舊資料為空，不回填 (非必填)
  "avatarCropBox"?: object // 上次裁切框在原圖上的位置與大小（x/y/width/height，選填 rotate/scale_x/scale_y），座標基準為被保存的原圖 (非必填)
  "name": string
  "email": string (email)
  "authSource": 
  {
    "id": string (uuid)
    "name": string
  }
  "company"?: string // 非必填
  "invitationCode"?: // 可能有不同的類型 (非必填)
  string // 非必填
  "apiKeys": [ // 取得使用者在指定組織中的 API 金鑰列表。

流程：
1. 從 request 中取得當前組織實例
2. 如果沒有組織實例（通常發生在第三方 SSO 登入時），則透過使用者的認證來源
   查找該認證來源的預設組織（is_auth_source_default_organization=True）

注意：
- 第三方 SSO 登入時 request 不會包含 organization_instance
- 需要透過 auth_source 和 is_auth_source_default_organization 標記來定位組織
    object
  ]
  "permissions": object // 取得使用者在當前組織中的權限（巢狀父子結構）。
  "resourcePermissions": object // 取得使用者在當前組織中的資源建立權限。
  "isOwner": boolean // 判斷使用者在當前組織中是否為 Owner。
  "maigptCapabilities": object // 成員在 MaiGPT 的有效內建功能能力（角色權限解析結果），供前端 show/hide。

無 member context（未綁組織）時解析結果為全開，與 resolver「缺資料不鎖死」
一致；前端隱藏僅為體驗層，權威把關在回覆路徑的 gate。
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "avatar": "https://example.com/file.jpg",
  "originalAvatar": "https://example.com/file.jpg",
  "avatarCropBox": null,
  "name": "回應字串",
  "email": "response@example.com",
  "authSource": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應字串"
  },
  "company": "回應字串",
  "invitationCode": "回應字串",
  "apiKeys": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  ],
  "permissions": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "resourcePermissions": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "isOwner": false,
  "maigptCapabilities": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  }
}
```

***

### 取得當前用戶權限 <a href="#permissions-list" id="permissions-list"></a>

GET `/api/v1/permissions/`

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/permissions/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/permissions/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/permissions/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/permissions/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
[
  {
    "id": string (uuid)
    "name": string
    "value": string
    "description": string
    "children": [
      object
    ]
  }
]
```

**回應範例值**

```json
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應字串",
    "value": "回應字串",
    "description": "回應字串",
    "children": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "回應範例名稱",
        "description": "回應範例描述"
      }
    ]
  }
]
```

***

### 取得指定組織的成員列表 <a href="#organizations-members-list" id="organizations-members-list"></a>

GET `/api/v1/organizations/{organizationPk}/members/`

#### 參數

| 參數名稱               | 必填 | 類型      | 說明                                                                                                                       |
| ------------------ | -- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| `organizationPk`   | ✅  | string  | A UUID string identifying this 組織 ID                                                                                     |
| `group`            | ❌  | string  |                                                                                                                          |
| `ids`              | ❌  | string  |                                                                                                                          |
| `inbox`            | ❌  | string  |                                                                                                                          |
| `isActive`         | ❌  | boolean |                                                                                                                          |
| `page`             | ❌  | integer | A page number within the paginated result set.                                                                           |
| `pageSize`         | ❌  | integer | Number of results to return per page.                                                                                    |
| `pagination`       | ❌  | string  | 是否分頁 (true/false)                                                                                                        |
| `query`            | ❌  | string  |                                                                                                                          |
| `search`           | ❌  | string  |                                                                                                                          |
| `withGroupSources` | ❌  | boolean | 為 true 時，\`groups\` 每個角色只列一次並多回 \`sources\`（這個角色被指派的方式：manual／ldap／scim／eip／cloudflare\_access，去重排序；預設角色是空陣列）。只有分頁的列表支援。 |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/?group=550e8400-e29b-41d4-a716-446655440000&ids=example&inbox=550e8400-e29b-41d4-a716-446655440000&isActive=true&page=1&pageSize=1&pagination=example&query=example&search=example&withGroupSources=true" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/?group=550e8400-e29b-41d4-a716-446655440000&ids=example&inbox=550e8400-e29b-41d4-a716-446655440000&isActive=true&page=1&pageSize=1&pagination=example&query=example&search=example&withGroupSources=true", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/?group=550e8400-e29b-41d4-a716-446655440000&ids=example&inbox=550e8400-e29b-41d4-a716-446655440000&isActive=true&page=1&pageSize=1&pagination=example&query=example&search=example&withGroupSources=true"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/?group=550e8400-e29b-41d4-a716-446655440000&ids=example&inbox=550e8400-e29b-41d4-a716-446655440000&isActive=true&page=1&pageSize=1&pagination=example&query=example&search=example&withGroupSources=true", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "id": string (uuid)
      "name": string
      "displayName": string // Name set by the organization owner for this organization only; empty string when not set (``name`` then falls back to the account name).
      "accountName": string // Account name of the member (shared across organizations); shown when display name is cleared.
      "isScimManaged": boolean // True when the member is provisioned by SCIM; the identity provider manages the member and the organization name cannot be changed manually.
      "email": string
      "isActive": boolean
      "isOwner": boolean // 檢查成員是否為組織擁有者（透過 OWNER Group）

使用快取避免同一 request 內的重複查詢
快取生命週期：在 member instance 存在期間有效

優先使用 annotation 的結果（如果有的話）避免重複查詢
      "permissions": [ // Compute the permission tree once per (organization, custom-group set) per request.

The tree depends only on the member's organization (default groups, feature
flags, plan whitelist), the member's custom groups, and the global ``Config``,
so members sharing a group set get the same result. A large role's
``pagination=false`` listing otherwise recomputes it per row — one Redis
``Config`` fetch plus the permission walk each time (issue #8436; the largest
prod role has 3,837 members and a single group set). The memo lives in the
serializer context, so it never outlives the request. Rows without the eager
loaded ``_custom_groups_cache`` (single-object paths) keep computing directly.
        object
      ]
      "groups": [
        object
      ]
      "creditQuotaRequired"?: boolean // When True, member must have an active quota to consume credits (非必填)
      "activeQuota": object // Return the most recent quota summary (active first), via prefetch to avoid N+1.
      "metadata": object // Organization-scoped member attributes, injected into LLM system prompt
      "availabilityStatus":  // Self-declared availability for auto-assignment. Paused members are skipped by the dispatch engine but can still be manually assigned or claim conversations. Not touched by SCIM provisioning.

* `available` - Available
* `paused` - Paused
      {
      }
      "createdAt": string (timestamp)
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應字串",
      "displayName": "回應字串",
      "accountName": "回應字串",
      "isScimManaged": false,
      "email": "回應字串",
      "isActive": false,
      "isOwner": false,
      "permissions": [
        {
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "name": "回應範例名稱",
          "description": "回應範例描述"
        }
      ],
      "groups": [
        {
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "name": "回應範例名稱",
          "description": "回應範例描述"
        }
      ],
      "creditQuotaRequired": false,
      "activeQuota": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "回應範例名稱",
        "description": "回應範例描述"
      },
      "metadata": null,
      "availabilityStatus": {},
      "createdAt": "回應字串"
    }
  ]
}
```

***

### 取得特定成員詳細資訊 <a href="#organizations-members-retrieve" id="organizations-members-retrieve"></a>

GET `/api/v1/organizations/{organizationPk}/members/{id}/`

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `id`             | ✅  | string | A UUID string identifying this 成員.   |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "displayName": string // Name set by the organization owner for this organization only; empty string when not set (``name`` then falls back to the account name).
  "accountName": string // Account name of the member (shared across organizations); shown when display name is cleared.
  "isScimManaged": boolean // True when the member is provisioned by SCIM; the identity provider manages the member and the organization name cannot be changed manually.
  "email": string
  "isActive": boolean
  "isOwner": boolean // 檢查成員是否為組織擁有者（透過 OWNER Group）

使用快取避免同一 request 內的重複查詢
快取生命週期：在 member instance 存在期間有效

優先使用 annotation 的結果（如果有的話）避免重複查詢
  "permissions": [ // Compute the permission tree once per (organization, custom-group set) per request.

The tree depends only on the member's organization (default groups, feature
flags, plan whitelist), the member's custom groups, and the global ``Config``,
so members sharing a group set get the same result. A large role's
``pagination=false`` listing otherwise recomputes it per row — one Redis
``Config`` fetch plus the permission walk each time (issue #8436; the largest
prod role has 3,837 members and a single group set). The memo lives in the
serializer context, so it never outlives the request. Rows without the eager
loaded ``_custom_groups_cache`` (single-object paths) keep computing directly.
    object
  ]
  "groups": [
    object
  ]
  "creditQuotaRequired"?: boolean // When True, member must have an active quota to consume credits (非必填)
  "activeQuota": object // Return the most recent quota summary (active first), via prefetch to avoid N+1.
  "metadata": object // Organization-scoped member attributes, injected into LLM system prompt
  "availabilityStatus":  // Self-declared availability for auto-assignment. Paused members are skipped by the dispatch engine but can still be manually assigned or claim conversations. Not touched by SCIM provisioning.

* `available` - Available
* `paused` - Paused
  {
  }
  "createdAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "displayName": "回應字串",
  "accountName": "回應字串",
  "isScimManaged": false,
  "email": "回應字串",
  "isActive": false,
  "isOwner": false,
  "permissions": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  ],
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  ],
  "creditQuotaRequired": false,
  "activeQuota": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "metadata": null,
  "availabilityStatus": {},
  "createdAt": "回應字串"
}
```

***

### 更新組織資訊 <a href="#organizations-update" id="organizations-update"></a>

PUT `/api/v1/organizations/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                 |
| ---- | -- | ------ | ---------------------------------- |
| `id` | ✅  | string | A UUID string identifying this 組織. |

#### 請求內容

**請求參數**

| 欄位                             | 類型           | 必填 | 說明                                                                                                                                                                                                          |
| ------------------------------ | ------------ | -- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name                           | string       | 是  |                                                                                                                                                                                                             |
| compactLogo                    | string (uri) | 否  |                                                                                                                                                                                                             |
| fullLogo                       | string (uri) | 否  |                                                                                                                                                                                                             |
| themePrimaryColor              | object       | 否  | UI 主題色，用於按鈕、連結等元素的顏色（HEX 格式，如 #0960bd）；留空表示未設定，前端退階使用系統品牌主色                                                                                                                                                 |
| hideChinaModels                | boolean      | 否  | When on, platform models whose developer is based in China (including ones added later) cannot be used in this organization: model menus, assistants, the API and AI Gateway exclude them, and live tran... |
| autoActivateNewChatbotChannels | boolean      | 否  | Initial state of the web chat and API channels of a new chatbot whose creator did not set them (duplicates, templates and API calls without the values included). When on, they start active; when off (... |
| companyName                    | string       | 否  | Applicant-reported company name collected at organization creation for approval review.                                                                                                                     |
| taxId                          | object       | 否  | Applicant-reported business tax ID (8 digits, optional). Stored as-is; not verified.                                                                                                                        |
| contactPhone                   | string       | 否  | Applicant-reported contact phone collected at organization creation for approval review.                                                                                                                    |
| applicationMetadata            | object       | 否  | Extra applicant-reported key-value fields collected at organization creation. Lets the frontend collect additional review fields without a schema migration; the core review fields (company name, tax I... |
| invitationCode                 | string       | 否  |                                                                                                                                                                                                             |

**請求結構範例**

```typescript
{
  "name": string
  "compactLogo"?: string (uri) // 非必填
  "fullLogo"?: string (uri) // 非必填
  "themePrimaryColor"?: // 可能有不同的類型 (非必填)
  string // UI 主題色，用於按鈕、連結等元素的顏色（HEX 格式，如 #0960bd）；留空表示未設定，前端退階使用系統品牌主色 (非必填)
  "hideChinaModels"?: boolean // When on, platform models whose developer is based in China (including ones added later) cannot be used in this organization: model menus, assistants, the API and AI Gateway exclude them, and live transcription lists China-developed speech engines as unavailable. Off by default; turn it on for public-sector or other organizations that must not use them. (非必填)
  "autoActivateNewChatbotChannels"?: boolean // Initial state of the web chat and API channels of a new chatbot whose creator did not set them (duplicates, templates and API calls without the values included). When on, they start active; when off (the platform default), they start inactive until a member turns them on. The creator can still override both channels in the New Chatbot dialog or the create API. The backstage (admin) channel is always active. Changing this does not affect existing chatbots. (非必填)
  "companyName"?: string // Applicant-reported company name collected at organization creation for approval review. (非必填)
  "taxId"?: // 可能有不同的類型 (非必填)
  string // Applicant-reported business tax ID (8 digits, optional). Stored as-is; not verified. (非必填)
  "contactPhone"?: string // Applicant-reported contact phone collected at organization creation for approval review. (非必填)
  "applicationMetadata"?: object // Extra applicant-reported key-value fields collected at organization creation. Lets the frontend collect additional review fields without a schema migration; the core review fields (company name, tax ID, contact phone) stay as named columns. (非必填)
  "invitationCode"?: string // 非必填
}
```

**請求範例值**

```json
{
  "id": "5b01e0b9-0b0e-4079-8150-d12015576d2c",
  "name": "Updated Org Name",
  "created_at": "1748336288000",
  "usage_statistics": {
    "chatbots_count": 0,
    "countable_chatbots_count": 0,
    "exempt_chatbots_by_mode": {},
    "allowed_chatbot_reply_modes": [],
    "can_create_chatbot": true,
    "create_chatbot_limit": 1,
    "current_month_words_count_total": 1000000,
    "current_month_used_words_count_total": 0,
    "current_month_used_conversations_count_total": 0,
    "available_upload_files_size_total": 104857600,
    "used_upload_file_size_total": 0
  },
  "organization_plan": {
    "id": "cac825e8-cb9b-4a16-b440-4ff6b2e73911",
    "plan_name": "免費方案",
    "expired_at": null
  },
  "is_trial": false,
  "expiration_days": null
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PUT "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "5b01e0b9-0b0e-4079-8150-d12015576d2c",
    "name": "Updated Org Name",
    "created_at": "1748336288000",
    "usage_statistics": {
      "chatbots_count": 0,
      "countable_chatbots_count": 0,
      "exempt_chatbots_by_mode": {},
      "allowed_chatbot_reply_modes": [],
      "can_create_chatbot": true,
      "create_chatbot_limit": 1,
      "current_month_words_count_total": 1000000,
      "current_month_used_words_count_total": 0,
      "current_month_used_conversations_count_total": 0,
      "available_upload_files_size_total": 104857600,
      "used_upload_file_size_total": 0
    },
    "organization_plan": {
      "id": "cac825e8-cb9b-4a16-b440-4ff6b2e73911",
      "plan_name": "免費方案",
      "expired_at": null
    },
    "is_trial": false,
    "expiration_days": null
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "id": "5b01e0b9-0b0e-4079-8150-d12015576d2c",
    "name": "Updated Org Name",
    "created_at": "1748336288000",
    "usage_statistics": {
      "chatbots_count": 0,
      "countable_chatbots_count": 0,
      "exempt_chatbots_by_mode": {},
      "allowed_chatbot_reply_modes": [],
      "can_create_chatbot": true,
      "create_chatbot_limit": 1,
      "current_month_words_count_total": 1000000,
      "current_month_used_words_count_total": 0,
      "current_month_used_conversations_count_total": 0,
      "available_upload_files_size_total": 104857600,
      "used_upload_file_size_total": 0
    },
    "organization_plan": {
      "id": "cac825e8-cb9b-4a16-b440-4ff6b2e73911",
      "plan_name": "免費方案",
      "expired_at": null
    },
    "is_trial": false,
    "expiration_days": null
  };

axios.put("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "id": "5b01e0b9-0b0e-4079-8150-d12015576d2c",
    "name": "Updated Org Name",
    "created_at": "1748336288000",
    "usage_statistics": {
        "chatbots_count": 0,
        "countable_chatbots_count": 0,
        "exempt_chatbots_by_mode": {},
        "allowed_chatbot_reply_modes": [],
        "can_create_chatbot": True,
        "create_chatbot_limit": 1,
        "current_month_words_count_total": 1000000,
        "current_month_used_words_count_total": 0,
        "current_month_used_conversations_count_total": 0,
        "available_upload_files_size_total": 104857600,
        "used_upload_file_size_total": 0
    },
    "organization_plan": {
        "id": "cac825e8-cb9b-4a16-b440-4ff6b2e73911",
        "plan_name": "免費方案",
        "expired_at": None
    },
    "is_trial": False,
    "expiration_days": None
}

response = requests.put(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->put("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'id' => '5b01e0b9-0b0e-4079-8150-d12015576d2c',
            'name' => 'Updated Org Name',
            'created_at' => '1748336288000',
            'usage_statistics' => [
                'chatbots_count' => 0,
                'countable_chatbots_count' => 0,
                'exempt_chatbots_by_mode' => new \stdClass(),
                'allowed_chatbot_reply_modes' => [],
                'can_create_chatbot' => true,
                'create_chatbot_limit' => 1,
                'current_month_words_count_total' => 1000000,
                'current_month_used_words_count_total' => 0,
                'current_month_used_conversations_count_total' => 0,
                'available_upload_files_size_total' => 104857600,
                'used_upload_file_size_total' => 0
            ],
            'organization_plan' => [
                'id' => 'cac825e8-cb9b-4a16-b440-4ff6b2e73911',
                'plan_name' => '免費方案',
                'expired_at' => null
            ],
            'is_trial' => false,
            'expiration_days' => null
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid) // 組織 ID
  "name": string // 組織名稱
  "created_at": string (timestamp) // 建立時間戳記
  "usage_statistics": { // 使用統計資訊
  {
    "chatbots_count"?: integer // 聊天機器人數量 (非必填)
    "countable_chatbots_count"?: integer // 佔用建立額度的聊天機器人數量（模式不在方案白名單內的不計入） (非必填)
    "exempt_chatbots_by_mode"?: object // 不佔額度的聊天機器人數量，依使其不計入的模式分組 (非必填)
    "allowed_chatbot_reply_modes"?: [ // 方案允許建立的回覆模式白名單（空陣列表示不限制） (非必填)
      string
    ]
    "can_create_chatbot"?: boolean // 是否可以建立聊天機器人 (非必填)
    "create_chatbot_limit"?: integer // 可建立的聊天機器人數量上限（-1 表示無上限、0 表示禁止建立） (非必填)
    "current_month_words_count_total"?: integer // 本月總字數限制 (非必填)
    "current_month_used_words_count_total"?: integer // 本月已使用字數 (非必填)
    "current_month_used_conversations_count_total"?: integer // 本月已使用對話數 (非必填)
    "available_upload_files_size_total"?: integer // 可上傳檔案總大小（位元組） (非必填)
    "used_upload_file_size_total"?: integer // 已使用上傳檔案大小（位元組） (非必填)
  }
  }
  "organization_plan": { // 組織方案資訊
  {
    "id"?: string (uuid) // 方案 ID (非必填)
    "plan_name"?: string // 方案名稱 (非必填)
    "expired_at"?: string (date-time) // 到期時間 (非必填)
  }
  }
  "is_trial"?: boolean // 是否為試用期。判定邏輯：組織只有一個試用方案且目前有效 (非必填)
  "expiration_days"?: integer // 已過期天數。正數=已過期天數，null=尚未到期或永久方案 (非必填)
}
```

**回應範例值**

```json
{
  "id": "5b01e0b9-0b0e-4079-8150-d12015576d2c",
  "name": "Updated Org Name",
  "created_at": "1748336288000",
  "usage_statistics": {
    "chatbots_count": 0,
    "countable_chatbots_count": 0,
    "exempt_chatbots_by_mode": {},
    "allowed_chatbot_reply_modes": [],
    "can_create_chatbot": true,
    "create_chatbot_limit": 1,
    "current_month_words_count_total": 1000000,
    "current_month_used_words_count_total": 0,
    "current_month_used_conversations_count_total": 0,
    "available_upload_files_size_total": 104857600,
    "used_upload_file_size_total": 0
  },
  "organization_plan": {
    "id": "cac825e8-cb9b-4a16-b440-4ff6b2e73911",
    "plan_name": "免費方案",
    "expired_at": null
  },
  "is_trial": false,
  "expiration_days": null
}
```

***

### 更新當前用戶詳細資訊 <a href="#users-current-update" id="users-current-update"></a>

PUT `/api/v1/users/current/`

#### 請求內容

**請求參數**

| 欄位             | 類型             | 必填 | 說明                                                                        |
| -------------- | -------------- | -- | ------------------------------------------------------------------------- |
| avatar         | string (uri)   | 否  |                                                                           |
| originalAvatar | string (uri)   | 否  | 使用者上傳的頭貼原圖（長邊已限制在 2048px 內），每次編輯都從這張重裁，避免在裁切結果上再裁而累積失真。本功能上線前的舊資料為空，不回填   |
| avatarCropBox  | object         | 否  | 上次裁切框在原圖上的位置與大小（x/y/width/height，選填 rotate/scale\_x/scale\_y），座標基準為被保存的原圖 |
| name           | string         | 是  |                                                                           |
| email          | string (email) | 是  |                                                                           |
| company        | string         | 否  |                                                                           |
| invitationCode | object         | 否  |                                                                           |

**請求結構範例**

```typescript
{
  "avatar"?: string (uri) // 非必填
  "originalAvatar"?: string (uri) // 使用者上傳的頭貼原圖（長邊已限制在 2048px 內），每次編輯都從這張重裁，避免在裁切結果上再裁而累積失真。本功能上線前的舊資料為空，不回填 (非必填)
  "avatarCropBox"?: object // 上次裁切框在原圖上的位置與大小（x/y/width/height，選填 rotate/scale_x/scale_y），座標基準為被保存的原圖 (非必填)
  "name": string
  "email": string (email)
  "company"?: string // 非必填
  "invitationCode"?: // 可能有不同的類型 (非必填)
  string // 非必填
}
```

**請求範例值**

```json
{
  "avatar": "https://example.com/file.jpg",
  "originalAvatar": "https://example.com/file.jpg",
  "avatarCropBox": null,
  "name": "範例名稱",
  "email": "user@example.com",
  "company": "範例字串",
  "invitationCode": null
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PUT "https://api.maiagent.ai/api/v1/users/current/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');
const FormData = require('form-data');

// 建立FormData對象
const formData = new FormData();
// 添加表單欄位

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    ...formData.getHeaders()
  }
};

axios.put("https://api.maiagent.ai/api/v1/users/current/", formData, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/users/current/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}

# 建立檔案和表單資料
files = {
    'file': ('example.pdf', open('example.pdf', 'rb'), 'application/pdf')
}

response = requests.put(url, files=files, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->put("https://api.maiagent.ai/api/v1/users/current/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ],
        'multipart' => [
            [
                'name' => 'file',
                'contents' => fopen('example.pdf', 'r'),
                'filename' => 'example.pdf'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "avatar"?: string (uri) // 非必填
  "originalAvatar"?: string (uri) // 使用者上傳的頭貼原圖（長邊已限制在 2048px 內），每次編輯都從這張重裁，避免在裁切結果上再裁而累積失真。本功能上線前的舊資料為空，不回填 (非必填)
  "avatarCropBox"?: object // 上次裁切框在原圖上的位置與大小（x/y/width/height，選填 rotate/scale_x/scale_y），座標基準為被保存的原圖 (非必填)
  "name": string
  "email": string (email)
  "authSource": 
  {
    "id": string (uuid)
    "name": string
  }
  "company"?: string // 非必填
  "invitationCode"?: // 可能有不同的類型 (非必填)
  string // 非必填
  "apiKeys": [ // 取得使用者在指定組織中的 API 金鑰列表。

流程：
1. 從 request 中取得當前組織實例
2. 如果沒有組織實例（通常發生在第三方 SSO 登入時），則透過使用者的認證來源
   查找該認證來源的預設組織（is_auth_source_default_organization=True）

注意：
- 第三方 SSO 登入時 request 不會包含 organization_instance
- 需要透過 auth_source 和 is_auth_source_default_organization 標記來定位組織
    object
  ]
  "permissions": object // 取得使用者在當前組織中的權限（巢狀父子結構）。
  "resourcePermissions": object // 取得使用者在當前組織中的資源建立權限。
  "isOwner": boolean // 判斷使用者在當前組織中是否為 Owner。
  "maigptCapabilities": object // 成員在 MaiGPT 的有效內建功能能力（角色權限解析結果），供前端 show/hide。

無 member context（未綁組織）時解析結果為全開，與 resolver「缺資料不鎖死」
一致；前端隱藏僅為體驗層，權威把關在回覆路徑的 gate。
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "avatar": "https://example.com/file.jpg",
  "originalAvatar": "https://example.com/file.jpg",
  "avatarCropBox": null,
  "name": "回應字串",
  "email": "response@example.com",
  "authSource": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應字串"
  },
  "company": "回應字串",
  "invitationCode": "回應字串",
  "apiKeys": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  ],
  "permissions": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "resourcePermissions": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "isOwner": false,
  "maigptCapabilities": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  }
}
```

***

### 更新成員所屬角色 <a href="#organizations-members-update-groups-create" id="organizations-members-update-groups-create"></a>

POST `/api/v1/organizations/{organizationPk}/members/{id}/update-groups/`

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `id`             | ✅  | string | A UUID string identifying this 成員.   |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 請求內容

**請求參數**

| 欄位     | 類型             | 必填 | 說明 |
| ------ | -------------- | -- | -- |
| groups | array\[string] | 是  |    |

**請求結構範例**

```typescript
{
  "groups": [
    string (uuid)
  ]
}
```

**請求範例值**

```json
{
  "groups": [
    "4e368ab4-c543-48a2-bbb8-f6f5a0bf6c61",
    "5f479bc5-d654-59b3-ccc9-g7g6b1cg7d72"
  ]
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/update-groups/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "groups": [
      "4e368ab4-c543-48a2-bbb8-f6f5a0bf6c61",
      "5f479bc5-d654-59b3-ccc9-g7g6b1cg7d72"
    ]
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "groups": [
      "4e368ab4-c543-48a2-bbb8-f6f5a0bf6c61",
      "5f479bc5-d654-59b3-ccc9-g7g6b1cg7d72"
    ]
  };

axios.post("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/update-groups/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/update-groups/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "groups": [
        "4e368ab4-c543-48a2-bbb8-f6f5a0bf6c61",
        "5f479bc5-d654-59b3-ccc9-g7g6b1cg7d72"
    ]
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/update-groups/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'groups' => [
                '4e368ab4-c543-48a2-bbb8-f6f5a0bf6c61',
                '5f479bc5-d654-59b3-ccc9-g7g6b1cg7d72'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "displayName": string // Name set by the organization owner for this organization only; empty string when not set (``name`` then falls back to the account name).
  "accountName": string // Account name of the member (shared across organizations); shown when display name is cleared.
  "isScimManaged": boolean // True when the member is provisioned by SCIM; the identity provider manages the member and the organization name cannot be changed manually.
  "email": string
  "isActive": boolean
  "isOwner": boolean // 檢查成員是否為組織擁有者（透過 OWNER Group）

使用快取避免同一 request 內的重複查詢
快取生命週期：在 member instance 存在期間有效

優先使用 annotation 的結果（如果有的話）避免重複查詢
  "permissions": [ // Compute the permission tree once per (organization, custom-group set) per request.

The tree depends only on the member's organization (default groups, feature
flags, plan whitelist), the member's custom groups, and the global ``Config``,
so members sharing a group set get the same result. A large role's
``pagination=false`` listing otherwise recomputes it per row — one Redis
``Config`` fetch plus the permission walk each time (issue #8436; the largest
prod role has 3,837 members and a single group set). The memo lives in the
serializer context, so it never outlives the request. Rows without the eager
loaded ``_custom_groups_cache`` (single-object paths) keep computing directly.
    object
  ]
  "groups": [
    object
  ]
  "creditQuotaRequired"?: boolean // When True, member must have an active quota to consume credits (非必填)
  "activeQuota": object // Return the most recent quota summary (active first), via prefetch to avoid N+1.
  "metadata": object // Organization-scoped member attributes, injected into LLM system prompt
  "availabilityStatus":  // Self-declared availability for auto-assignment. Paused members are skipped by the dispatch engine but can still be manually assigned or claim conversations. Not touched by SCIM provisioning.

* `available` - Available
* `paused` - Paused
  {
  }
  "createdAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "displayName": "回應字串",
  "accountName": "回應字串",
  "isScimManaged": false,
  "email": "回應字串",
  "isActive": false,
  "isOwner": false,
  "permissions": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  ],
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  ],
  "creditQuotaRequired": false,
  "activeQuota": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "metadata": null,
  "availabilityStatus": {},
  "createdAt": "回應字串"
}
```

**狀態碼: 400**

**回應結構範例**

```typescript
object
```

***

### 修改成員名稱 <a href="#organizations-members-display-name-partial-update" id="organizations-members-display-name-partial-update"></a>

PATCH `/api/v1/organizations/{organizationPk}/members/{id}/display-name/`

{% hint style="info" %}
**所需權限**：只有組織擁有者可以呼叫，具成員管理權限的非擁有者也會收到 `403`。只修改成員在本組織顯示的名稱（組織內名稱），不改成員的帳號名稱，也不影響成員所在的其他組織；角色、額度、自訂屬性等其他成員資料不受影響。`displayName` 前後空白會去除，最多 255 字，不需唯一；傳空字串或只有空白代表清除，成員改為顯示帳號名稱（`accountName`）。與目前顯示的名稱（`name`，未設定組織內名稱時即帳號名稱）相同時視為沒有變更，不寫入、不記活動日誌，照樣回 `200`。成員由 SCIM 同步管理（`isScimManaged` 為 `true`）時回 `400`，請在身分提供者端修改；成員不屬於此組織回 `404`。成功回傳與「取得特定成員詳細資訊」相同的成員物件，`name` 即為新的顯示名稱；有實際變更時會記入組織的活動日誌。
{% endhint %}

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `id`             | ✅  | string | A UUID string identifying this 成員.   |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 請求內容

**請求參數**

| 欄位          | 類型     | 必填 | 說明                                                                                                                                                                   |
| ----------- | ------ | -- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| displayName | string | 是  | New name of the member in this organization. Leading/trailing whitespace is trimmed; an empty or whitespace-only value clears it so the account name is shown again. |

**請求結構範例**

```typescript
{
  "displayName": string // New name of the member in this organization. Leading/trailing whitespace is trimmed; an empty or whitespace-only value clears it so the account name is shown again.
}
```

**請求範例值**

```json
{
  "displayName": "範例字串"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PATCH "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/display-name/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "範例字串"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "displayName": "範例字串"
  };

axios.patch("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/display-name/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/display-name/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "displayName": "範例字串"
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->patch("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/display-name/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'displayName' => '範例字串'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "displayName": string // Name set by the organization owner for this organization only; empty string when not set (``name`` then falls back to the account name).
  "accountName": string // Account name of the member (shared across organizations); shown when display name is cleared.
  "isScimManaged": boolean // True when the member is provisioned by SCIM; the identity provider manages the member and the organization name cannot be changed manually.
  "email": string
  "isActive": boolean
  "isOwner": boolean // 檢查成員是否為組織擁有者（透過 OWNER Group）

使用快取避免同一 request 內的重複查詢
快取生命週期：在 member instance 存在期間有效

優先使用 annotation 的結果（如果有的話）避免重複查詢
  "permissions": [ // Compute the permission tree once per (organization, custom-group set) per request.

The tree depends only on the member's organization (default groups, feature
flags, plan whitelist), the member's custom groups, and the global ``Config``,
so members sharing a group set get the same result. A large role's
``pagination=false`` listing otherwise recomputes it per row — one Redis
``Config`` fetch plus the permission walk each time (issue #8436; the largest
prod role has 3,837 members and a single group set). The memo lives in the
serializer context, so it never outlives the request. Rows without the eager
loaded ``_custom_groups_cache`` (single-object paths) keep computing directly.
    object
  ]
  "groups": [
    object
  ]
  "creditQuotaRequired"?: boolean // When True, member must have an active quota to consume credits (非必填)
  "activeQuota": object // Return the most recent quota summary (active first), via prefetch to avoid N+1.
  "metadata": object // Organization-scoped member attributes, injected into LLM system prompt
  "availabilityStatus":  // Self-declared availability for auto-assignment. Paused members are skipped by the dispatch engine but can still be manually assigned or claim conversations. Not touched by SCIM provisioning.

* `available` - Available
* `paused` - Paused
  {
  }
  "createdAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "displayName": "回應字串",
  "accountName": "回應字串",
  "isScimManaged": false,
  "email": "回應字串",
  "isActive": false,
  "isOwner": false,
  "permissions": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  ],
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  ],
  "creditQuotaRequired": false,
  "activeQuota": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "metadata": null,
  "availabilityStatus": {},
  "createdAt": "回應字串"
}
```

**狀態碼: 400 - 成員由 SCIM 同步管理、名稱超過 255 字，或沒有帶 displayName**

**回應結構範例**

```typescript
{
  "displayName"?: [ // 錯誤原因：成員由 SCIM 同步管理、名稱超過 255 字，或沒有帶 displayName (非必填)
    string
  ]
}
```

**回應範例值**

```json
{
  "displayName": [
    "此成員的名稱由身分提供者（SCIM）同步管理，無法手動修改"
  ]
}
```

**狀態碼: 403 - 呼叫者不是組織擁有者**

**回應結構範例**

```typescript
{
  "detail"?: string // 非必填
}
```

**回應範例值**

```json
{
  "detail": "只有組織擁有者可以修改名稱"
}
```

**狀態碼: 404 - 成員不存在或不屬於本組織**

***

### 邀請成員加入組織 <a href="#auth-unified-invitations-create" id="auth-unified-invitations-create"></a>

POST `/api/v1/auth/unified-invitations/`

{% hint style="info" %}
以 API Key 所屬的組織為準，需要「組織概覽權限」（組織擁有者不受限）。`emails` 一次最多 100 個；已註冊的使用者直接成為成員（回應 `members`），尚未註冊的 email 寄出邀請信、註冊後加入（回應 `mailInvitations`），已是成員的列在 `skippedEmails`。`groups` 指定加入後的角色，格式為 `[{"id": "角色 ID"}]`。可帶 `creditQuota` 替這批受邀者預設個人額度，加入時才配發：`quotaLimit`（必填）、`validUntil`（選填，ISO 8601 字串如 `2026-12-31T23:59:59+08:00`，或 13 位數毫秒時間戳，字串或數字皆可；未帶時區以台灣時間計；須晚於現在；不帶表示不過期）、`resetPeriod`（`none`／`daily`／`weekly`／`monthly`，預設 `none`）、`note`（選填）。帶 `creditQuota` 另需「Credit 管理權限」，且組織須為 Credit 計費模式；不帶則套用 [新成員預設額度](https://docs.maiagent.ai/api/api-reference/credit#credit-wallets-new-member-quota-policy-retrieve)（若有啟用）。
{% endhint %}

#### 請求內容

**請求參數**

| 欄位                      | 類型                                                       | 必填 | 說明                                                                    |
| ----------------------- | -------------------------------------------------------- | -- | --------------------------------------------------------------------- |
| creditQuota             | object (含 4 個屬性: quotaLimit, validUntil, resetPeriod...) | 否  | Optional credit quota allocated to the invitee when they join.        |
| creditQuota.quotaLimit  | string (decimal)                                         | 是  |                                                                       |
| creditQuota.validUntil  | object                                                   | 否  | ISO 8601 date-time or 13-digit epoch milliseconds (string or number). |
| creditQuota.resetPeriod | object                                                   | 否  |                                                                       |
| creditQuota.note        | string                                                   | 否  |                                                                       |
| groups                  | array\[IdName]                                           | 否  |                                                                       |
| emails                  | array\[string]                                           | 是  | Email address list to invite. Up to 100 emails.                       |

**請求結構範例**

```typescript
{
  "creditQuota"?:  // Optional credit quota allocated to the invitee when they join. (非必填)
  {
    "quotaLimit": string (decimal)
    "validUntil"?: // 可能有不同的類型 (非必填)
    string (date-time) // ISO 8601 date-time or 13-digit epoch milliseconds (string or number). (非必填)
    "resetPeriod"?:  // 非必填
    {
    }
    "note"?: string // 非必填
  }
  "groups"?: [ // 非必填
    {
      "id": string (uuid)
    }
  ]
  "emails": [ // Email address list to invite. Up to 100 emails.
    string (email)
  ]
}
```

**請求範例值**

```json
{
  "emails": [
    "user@example.com",
    "user2@example.com"
  ],
  "groups": [
    {
      "id": "12345678-1234-5678-1234-567812345678"
    }
  ]
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/auth/unified-invitations/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      "user@example.com",
      "user2@example.com"
    ],
    "groups": [
      {
        "id": "12345678-1234-5678-1234-567812345678"
      }
    ]
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "emails": [
      "user@example.com",
      "user2@example.com"
    ],
    "groups": [
      {
        "id": "12345678-1234-5678-1234-567812345678"
      }
    ]
  };

axios.post("https://api.maiagent.ai/api/v1/auth/unified-invitations/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/auth/unified-invitations/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "emails": [
        "user@example.com",
        "user2@example.com"
    ],
    "groups": [
        {
            "id": "12345678-1234-5678-1234-567812345678"
        }
    ]
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/auth/unified-invitations/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'emails' => [
                'user@example.com',
                'user2@example.com'
            ],
            'groups' => [
                [
                    'id' => '12345678-1234-5678-1234-567812345678'
                ]
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "members": [
    {
      "id": string (uuid)
      "email": string (email)
      "name": string
    }
  ]
  "mailInvitations": [
    {
      "creditQuota": 
      {
        "quotaLimit": string (decimal)
        "validUntil": string (date-time)
        "resetPeriod": 
        {
        }
        "note": string
      }
      "creditQuotaSource": string
      "id": string (uuid)
      "email": string (email)
      "displayStatus": string
      "code": string
      "inviter": string (uuid)
      "organization"?: string (uuid) // 非必填
      "groups"?: [ // 非必填
        {
          "id": string (uuid)
          "name": string
        }
      ]
      "createdAt"?: string (timestamp) // 非必填
      "acceptedAt"?: string (timestamp) // 非必填
      "lastSentAt": string (timestamp)
      "failureReason": string
      "retryCount": integer
      "canResend": boolean
    }
  ]
  "skippedEmails": [
    string (email)
  ]
}
```

**回應範例值**

```json
{
  "members": [
    {
      "id": "33333333-3333-3333-3333-333333333333",
      "email": "user2@example.com",
      "name": "User Two"
    }
  ],
  "mailInvitations": [
    {
      "id": "87654321-4321-8765-4321-876543210000",
      "email": "user@example.com",
      "displayStatus": "pending",
      "creditQuota": {
        "quotaLimit": "500.000000",
        "validUntil": "2026-12-31T15:59:59+00:00",
        "resetPeriod": "monthly",
        "note": "新進同仁額度"
      },
      "creditQuotaSource": "invitation_override"
    }
  ],
  "skippedEmails": []
}
```

**狀態碼: 400 - 請求內容不正確，例如 email 格式錯誤、角色不存在、\`creditQuota.validUntil\` 格式錯誤或已過期，或組織不是 Credit 計費模式卻帶了 \`creditQuota\`**

**狀態碼: 403 - 沒有組織概覽權限、帶了 \`creditQuota\` 但沒有 Credit 管理權限，或非組織擁有者指定擁有者角色／重新邀請帶擁有者角色的待處理邀請**

***

### 列出組織邀請信紀錄 <a href="#auth-organization-mail-invitations-list" id="auth-organization-mail-invitations-list"></a>

GET `/api/v1/auth/organization-mail-invitations/`

{% hint style="info" %}
查詢邀請信的寄送與接受狀態，`status` 參數篩選，可多選（例如 `status=pending&status=mail_failed`），不帶則回傳全部狀態；`pagination=false` 取消分頁。有「組織概覽權限」可看到全組織的邀請（指定擁有者角色的邀請只有組織擁有者看得到），否則只看到自己發出的。
{% endhint %}

#### 參數

| 參數名稱         | 必填 | 類型      | 說明                                                         |
| ------------ | -- | ------- | ---------------------------------------------------------- |
| `pagination` | ❌  | boolean | 是否分頁                                                       |
| `status`     | ❌  | string  | 邀請狀態，可多選（例如 status=pending\&status=mail\_failed）；不帶則回傳全部狀態 |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/auth/organization-mail-invitations/?pagination=true&status=accepted" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/auth/organization-mail-invitations/?pagination=true&status=accepted", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/auth/organization-mail-invitations/?pagination=true&status=accepted"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/auth/organization-mail-invitations/?pagination=true&status=accepted", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
[
  {
    "creditQuota": 
    {
      "quotaLimit": string (decimal)
      "validUntil": string (date-time)
      "resetPeriod": 
      {
      }
      "note": string
    }
    "creditQuotaSource": string
    "id": string (uuid)
    "email": string (email)
    "displayStatus": string
    "code": string
    "inviter": string (uuid)
    "organization"?: string (uuid) // 非必填
    "groups"?: [ // 非必填
      {
        "id": string (uuid)
        "name": string
      }
    ]
    "createdAt"?: string (timestamp) // 非必填
    "acceptedAt"?: string (timestamp) // 非必填
    "lastSentAt": string (timestamp)
    "failureReason": string
    "retryCount": integer
    "canResend": boolean
  }
]
```

**回應範例值**

```json
[
  {
    "creditQuota": {
      "quotaLimit": "回應字串",
      "validUntil": "2026-12-31T23:59:59+08:00",
      "resetPeriod": {},
      "note": "回應字串"
    },
    "creditQuotaSource": "回應字串",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "response@example.com",
    "displayStatus": "回應字串",
    "code": "回應字串",
    "inviter": "550e8400-e29b-41d4-a716-446655440000",
    "organization": "550e8400-e29b-41d4-a716-446655440000",
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "回應字串"
      }
    ],
    "createdAt": "回應字串",
    "acceptedAt": "回應字串",
    "lastSentAt": "回應字串",
    "failureReason": "回應字串",
    "retryCount": 456,
    "canResend": false
  }
]
```

***

### 重寄組織邀請信 <a href="#auth-organization-mail-invitations-resend-create" id="auth-organization-mail-invitations-resend-create"></a>

POST `/api/v1/auth/organization-mail-invitations/{id}/resend/`

{% hint style="info" %}
需要「組織概覽權限」，不需請求內容。只有待接受或寄送失敗的邀請可重寄（已接受、已撤銷回 `400`），最多重寄 3 次，每次間隔至少 5 分鐘。
{% endhint %}

#### 參數

| 參數名稱 | 必填 | 類型     | 說明 |
| ---- | -- | ------ | -- |
| `id` | ✅  | string |    |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/auth/organization-mail-invitations/550e8400-e29b-41d4-a716-446655440000/resend/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.post("https://api.maiagent.ai/api/v1/auth/organization-mail-invitations/550e8400-e29b-41d4-a716-446655440000/resend/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/auth/organization-mail-invitations/550e8400-e29b-41d4-a716-446655440000/resend/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.post(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/auth/organization-mail-invitations/550e8400-e29b-41d4-a716-446655440000/resend/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "creditQuota": 
  {
    "quotaLimit": string (decimal)
    "validUntil": string (date-time)
    "resetPeriod": 
    {
    }
    "note": string
  }
  "creditQuotaSource": string
  "id": string (uuid)
  "email": string (email)
  "displayStatus": string
  "code": string
  "inviter": string (uuid)
  "organization"?: string (uuid) // 非必填
  "groups"?: [ // 非必填
    {
      "id": string (uuid)
      "name": string
    }
  ]
  "createdAt"?: string (timestamp) // 非必填
  "acceptedAt"?: string (timestamp) // 非必填
  "lastSentAt": string (timestamp)
  "failureReason": string
  "retryCount": integer
  "canResend": boolean
}
```

**回應範例值**

```json
{
  "creditQuota": {
    "quotaLimit": "回應字串",
    "validUntil": "2026-12-31T23:59:59+08:00",
    "resetPeriod": {},
    "note": "回應字串"
  },
  "creditQuotaSource": "回應字串",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "response@example.com",
  "displayStatus": "回應字串",
  "code": "回應字串",
  "inviter": "550e8400-e29b-41d4-a716-446655440000",
  "organization": "550e8400-e29b-41d4-a716-446655440000",
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應字串"
    }
  ],
  "createdAt": "回應字串",
  "acceptedAt": "回應字串",
  "lastSentAt": "回應字串",
  "failureReason": "回應字串",
  "retryCount": 456,
  "canResend": false
}
```

***

### 列出組織的 API Key <a href="#organizations-api-keys-list" id="organizations-api-keys-list"></a>

GET `/api/v1/organizations/{organizationPk}/api-keys/`

{% hint style="info" %}
管理者視角的 API Key 管理，需要「API Key 管理權限」。成員可同時持有多把有效金鑰，可先簽新、部署後再撤舊。取得方式見 [API 認證方式](https://docs.maiagent.ai/api/preparation/authentication)。
{% endhint %}

#### 參數

| 參數名稱             | 必填 | 類型      | 說明                                             |
| ---------------- | -- | ------- | ---------------------------------------------- |
| `organizationPk` | ✅  | string  | A UUID string identifying this 組織 ID           |
| `page`           | ❌  | integer | A page number within the paginated result set. |
| `pageSize`       | ❌  | integer | Number of results to return per page.          |
| `query`          | ❌  | string  |                                                |
| `source`         | ❌  | string  |                                                |
| `status`         | ❌  | string  |                                                |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/?page=1&pageSize=1&query=example&source=example&status=example" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/?page=1&pageSize=1&query=example&source=example&status=example", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/?page=1&pageSize=1&query=example&source=example&status=example"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/?page=1&pageSize=1&query=example&source=example&status=example", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "id": string
      "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (非必填)
      "prefix": string
      "status": string
      "source": string
      "isActive"?: boolean // Reversible enable switch. A disabled key is rejected exactly like an unknown key (generic 401, no information leak), but keeps its secret and usage history and can be re-enabled at any time — unlike the irreversible revoked flag. (非必填)
      "rateLimitRpm"?: integer // Max requests per minute across every platform API this key can call. Null = unlimited. (非必填)
      "rateLimitTpm"?: integer // Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited. (非必填)
      "creditBudgetDaily"?: string (decimal) // Max credits this key may spend through the AI Gateway per natural day (Asia/Taipei). Once reached, further inference calls are refused with 402 key_budget_exceeded until the next day. Null = unlimited. (非必填)
      "creditBudgetMonthly"?: string (decimal) // Max credits this key may spend through the AI Gateway per calendar month (Asia/Taipei). Once reached, further inference calls are refused with 402 key_budget_exceeded until the next month. Null = unlimited. (非必填)
      "creditUsedToday": string (decimal)
      "creditUsedThisMonth": string (decimal)
      "gatewayAllowedLlmCount": integer // Size of the gateway allow-list, when the queryset annotated it.

0 means "no restriction" (see ``api_key_allowed_llm_ids``). ``None``
on surfaces that did not annotate (login payload, PAT list) so a
missing count is never mistaken for "unrestricted".
      "expiryDate"?: string (timestamp) // Once API key expires, clients cannot use it anymore. (非必填)
      "createdAt": string (timestamp)
      "lastUsedAt"?: string (timestamp) // 非必填
      "member": object
      "createdByName": string
      "revokedAt"?: string (timestamp) // 非必填
      "revokedByName": string
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "id": "回應字串",
      "name": "回應字串",
      "prefix": "回應字串",
      "status": "回應字串",
      "source": "回應字串",
      "isActive": false,
      "rateLimitRpm": 456,
      "rateLimitTpm": 456,
      "creditBudgetDaily": "回應字串",
      "creditBudgetMonthly": "回應字串",
      "creditUsedToday": "回應字串",
      "creditUsedThisMonth": "回應字串",
      "gatewayAllowedLlmCount": 456,
      "expiryDate": "回應字串",
      "createdAt": "回應字串",
      "lastUsedAt": "回應字串",
      "member": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "回應範例名稱",
        "description": "回應範例描述"
      },
      "createdByName": "回應字串",
      "revokedAt": "回應字串",
      "revokedByName": "回應字串"
    }
  ]
}
```

**狀態碼: 403 - 權限不足**

***

### 替成員簽發 API Key <a href="#organizations-api-keys-create" id="organizations-api-keys-create"></a>

POST `/api/v1/organizations/{organizationPk}/api-keys/`

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 請求內容

**請求參數**

| 欄位                  | 類型                 | 必填 | 說明 |
| ------------------- | ------------------ | -- | -- |
| name                | string             | 是  |    |
| expiryDate          | string (timestamp) | 否  |    |
| memberId            | string (uuid)      | 是  |    |
| isActive            | boolean            | 否  |    |
| creditBudgetDaily   | string (decimal)   | 否  |    |
| creditBudgetMonthly | string (decimal)   | 否  |    |

**請求結構範例**

```typescript
{
  "name": string
  "expiryDate"?: string (timestamp) // 非必填
  "memberId": string (uuid)
  "isActive"?: boolean // 非必填
  "creditBudgetDaily"?: string (decimal) // 非必填
  "creditBudgetMonthly"?: string (decimal) // 非必填
}
```

**請求範例值**

```json
{
  "name": "My API Key",
  "member_id": "00000000-0000-0000-0000-000000000000",
  "expiry_date": "2027-12-31T23:59:59Z"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My API Key",
    "member_id": "00000000-0000-0000-0000-000000000000",
    "expiry_date": "2027-12-31T23:59:59Z"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "name": "My API Key",
    "member_id": "00000000-0000-0000-0000-000000000000",
    "expiry_date": "2027-12-31T23:59:59Z"
  };

axios.post("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "name": "My API Key",
    "member_id": "00000000-0000-0000-0000-000000000000",
    "expiry_date": "2027-12-31T23:59:59Z"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'name' => 'My API Key',
            'member_id' => '00000000-0000-0000-0000-000000000000',
            'expiry_date' => '2027-12-31T23:59:59Z'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "id": string
  "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (非必填)
  "prefix": string
  "key": string // The full API key. Shown only in this response and never stored, so it
cannot be retrieved again.
  "status": string
  "source": string
  "isActive"?: boolean // Reversible enable switch. A disabled key is rejected exactly like an unknown key (generic 401, no information leak), but keeps its secret and usage history and can be re-enabled at any time — unlike the irreversible revoked flag. (非必填)
  "expiryDate"?: string (timestamp) // Once API key expires, clients cannot use it anymore. (非必填)
  "createdAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "回應字串",
  "name": "回應字串",
  "prefix": "回應字串",
  "key": "回應字串",
  "status": "回應字串",
  "source": "回應字串",
  "isActive": false,
  "expiryDate": "回應字串",
  "createdAt": "回應字串"
}
```

**狀態碼: 400 - 驗證錯誤（例如：名稱空白、到期日已過）**

**狀態碼: 403 - 權限不足**

***

### 取得特定 API Key <a href="#organizations-api-keys-retrieve" id="organizations-api-keys-retrieve"></a>

GET `/api/v1/organizations/{organizationPk}/api-keys/{id}/`

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `id`             | ✅  | string |                                      |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string
  "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (非必填)
  "prefix": string
  "status": string
  "source": string
  "isActive"?: boolean // Reversible enable switch. A disabled key is rejected exactly like an unknown key (generic 401, no information leak), but keeps its secret and usage history and can be re-enabled at any time — unlike the irreversible revoked flag. (非必填)
  "rateLimitRpm"?: integer // Max requests per minute across every platform API this key can call. Null = unlimited. (非必填)
  "rateLimitTpm"?: integer // Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited. (非必填)
  "creditBudgetDaily"?: string (decimal) // Max credits this key may spend through the AI Gateway per natural day (Asia/Taipei). Once reached, further inference calls are refused with 402 key_budget_exceeded until the next day. Null = unlimited. (非必填)
  "creditBudgetMonthly"?: string (decimal) // Max credits this key may spend through the AI Gateway per calendar month (Asia/Taipei). Once reached, further inference calls are refused with 402 key_budget_exceeded until the next month. Null = unlimited. (非必填)
  "creditUsedToday": string (decimal)
  "creditUsedThisMonth": string (decimal)
  "gatewayAllowedLlmCount": integer // Size of the gateway allow-list, when the queryset annotated it.

0 means "no restriction" (see ``api_key_allowed_llm_ids``). ``None``
on surfaces that did not annotate (login payload, PAT list) so a
missing count is never mistaken for "unrestricted".
  "expiryDate"?: string (timestamp) // Once API key expires, clients cannot use it anymore. (非必填)
  "createdAt": string (timestamp)
  "lastUsedAt"?: string (timestamp) // 非必填
  "member": object
  "createdByName": string
  "revokedAt"?: string (timestamp) // 非必填
  "revokedByName": string
  "gatewayAllowedLlmIds": [
    string (uuid)
  ]
}
```

**回應範例值**

```json
{
  "id": "回應字串",
  "name": "回應字串",
  "prefix": "回應字串",
  "status": "回應字串",
  "source": "回應字串",
  "isActive": false,
  "rateLimitRpm": 456,
  "rateLimitTpm": 456,
  "creditBudgetDaily": "回應字串",
  "creditBudgetMonthly": "回應字串",
  "creditUsedToday": "回應字串",
  "creditUsedThisMonth": "回應字串",
  "gatewayAllowedLlmCount": 456,
  "expiryDate": "回應字串",
  "createdAt": "回應字串",
  "lastUsedAt": "回應字串",
  "member": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "createdByName": "回應字串",
  "revokedAt": "回應字串",
  "revokedByName": "回應字串",
  "gatewayAllowedLlmIds": [
    "550e8400-e29b-41d4-a716-446655440000"
  ]
}
```

***

### 更新 API Key 設定 <a href="#organizations-api-keys-partial-update" id="organizations-api-keys-partial-update"></a>

PATCH `/api/v1/organizations/{organizationPk}/api-keys/{id}/`

{% hint style="info" %}
可調整啟用狀態、每分鐘請求數（RPM）、到期時間；停用可逆，撤銷用 `DELETE`。
{% endhint %}

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `id`             | ✅  | string |                                      |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 請求內容

**請求參數**

| 欄位                  | 類型                 | 必填 | 說明                                                                                                                                                                                                            |
| ------------------- | ------------------ | -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name                | string             | 否  | A free-form name for the API key. Need not be unique. 50 characters max.                                                                                                                                      |
| isActive            | boolean            | 否  | Reversible enable switch. A disabled key is rejected exactly like an unknown key (generic 401, no information leak), but keeps its secret and usage history and can be re-enabled at any time — unlike t...   |
| rateLimitRpm        | integer            | 否  | Max requests per minute across every platform API this key can call. Null = unlimited.                                                                                                                        |
| rateLimitTpm        | integer            | 否  | Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited.                                                                                                                       |
| creditBudgetDaily   | string (decimal)   | 否  | Max credits this key may spend through the AI Gateway per natural day (Asia/Taipei). Once reached, further inference calls are refused with 402 key\_budget\_exceeded until the next day. Null = unlimited... |
| creditBudgetMonthly | string (decimal)   | 否  | Max credits this key may spend through the AI Gateway per calendar month (Asia/Taipei). Once reached, further inference calls are refused with 402 key\_budget\_exceeded until the next month. Null = unli... |
| expiryDate          | string (timestamp) | 否  | Once API key expires, clients cannot use it anymore.                                                                                                                                                          |
| lastUsedAt          | string (timestamp) | 否  |                                                                                                                                                                                                               |
| revokedAt           | string (timestamp) | 否  |                                                                                                                                                                                                               |

**請求結構範例**

```typescript
{
  "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (非必填)
  "isActive"?: boolean // Reversible enable switch. A disabled key is rejected exactly like an unknown key (generic 401, no information leak), but keeps its secret and usage history and can be re-enabled at any time — unlike the irreversible revoked flag. (非必填)
  "rateLimitRpm"?: integer // Max requests per minute across every platform API this key can call. Null = unlimited. (非必填)
  "rateLimitTpm"?: integer // Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited. (非必填)
  "creditBudgetDaily"?: string (decimal) // Max credits this key may spend through the AI Gateway per natural day (Asia/Taipei). Once reached, further inference calls are refused with 402 key_budget_exceeded until the next day. Null = unlimited. (非必填)
  "creditBudgetMonthly"?: string (decimal) // Max credits this key may spend through the AI Gateway per calendar month (Asia/Taipei). Once reached, further inference calls are refused with 402 key_budget_exceeded until the next month. Null = unlimited. (非必填)
  "expiryDate"?: string (timestamp) // Once API key expires, clients cannot use it anymore. (非必填)
  "lastUsedAt"?: string (timestamp) // 非必填
  "revokedAt"?: string (timestamp) // 非必填
}
```

**請求範例值**

```json
{
  "name": "範例名稱",
  "isActive": true,
  "rateLimitRpm": 123,
  "rateLimitTpm": 123,
  "creditBudgetDaily": "範例字串",
  "creditBudgetMonthly": "範例字串",
  "expiryDate": "範例字串",
  "lastUsedAt": "範例字串",
  "revokedAt": "範例字串"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PATCH "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "範例名稱",
    "isActive": true,
    "rateLimitRpm": 123,
    "rateLimitTpm": 123,
    "creditBudgetDaily": "範例字串",
    "creditBudgetMonthly": "範例字串",
    "expiryDate": "範例字串",
    "lastUsedAt": "範例字串",
    "revokedAt": "範例字串"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "name": "範例名稱",
    "isActive": true,
    "rateLimitRpm": 123,
    "rateLimitTpm": 123,
    "creditBudgetDaily": "範例字串",
    "creditBudgetMonthly": "範例字串",
    "expiryDate": "範例字串",
    "lastUsedAt": "範例字串",
    "revokedAt": "範例字串"
  };

axios.patch("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "name": "範例名稱",
    "isActive": True,
    "rateLimitRpm": 123,
    "rateLimitTpm": 123,
    "creditBudgetDaily": "範例字串",
    "creditBudgetMonthly": "範例字串",
    "expiryDate": "範例字串",
    "lastUsedAt": "範例字串",
    "revokedAt": "範例字串"
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->patch("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'name' => '範例名稱',
            'isActive' => true,
            'rateLimitRpm' => 123,
            'rateLimitTpm' => 123,
            'creditBudgetDaily' => '範例字串',
            'creditBudgetMonthly' => '範例字串',
            'expiryDate' => '範例字串',
            'lastUsedAt' => '範例字串',
            'revokedAt' => '範例字串'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string
  "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (非必填)
  "prefix": string
  "status": string
  "source": string
  "isActive"?: boolean // Reversible enable switch. A disabled key is rejected exactly like an unknown key (generic 401, no information leak), but keeps its secret and usage history and can be re-enabled at any time — unlike the irreversible revoked flag. (非必填)
  "rateLimitRpm"?: integer // Max requests per minute across every platform API this key can call. Null = unlimited. (非必填)
  "rateLimitTpm"?: integer // Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited. (非必填)
  "creditBudgetDaily"?: string (decimal) // Max credits this key may spend through the AI Gateway per natural day (Asia/Taipei). Once reached, further inference calls are refused with 402 key_budget_exceeded until the next day. Null = unlimited. (非必填)
  "creditBudgetMonthly"?: string (decimal) // Max credits this key may spend through the AI Gateway per calendar month (Asia/Taipei). Once reached, further inference calls are refused with 402 key_budget_exceeded until the next month. Null = unlimited. (非必填)
  "creditUsedToday": string (decimal)
  "creditUsedThisMonth": string (decimal)
  "gatewayAllowedLlmCount": integer // Size of the gateway allow-list, when the queryset annotated it.

0 means "no restriction" (see ``api_key_allowed_llm_ids``). ``None``
on surfaces that did not annotate (login payload, PAT list) so a
missing count is never mistaken for "unrestricted".
  "expiryDate"?: string (timestamp) // Once API key expires, clients cannot use it anymore. (非必填)
  "createdAt": string (timestamp)
  "lastUsedAt"?: string (timestamp) // 非必填
  "member": object
  "createdByName": string
  "revokedAt"?: string (timestamp) // 非必填
  "revokedByName": string
  "gatewayAllowedLlmIds": [
    string (uuid)
  ]
}
```

**回應範例值**

```json
{
  "id": "回應字串",
  "name": "回應字串",
  "prefix": "回應字串",
  "status": "回應字串",
  "source": "回應字串",
  "isActive": false,
  "rateLimitRpm": 456,
  "rateLimitTpm": 456,
  "creditBudgetDaily": "回應字串",
  "creditBudgetMonthly": "回應字串",
  "creditUsedToday": "回應字串",
  "creditUsedThisMonth": "回應字串",
  "gatewayAllowedLlmCount": 456,
  "expiryDate": "回應字串",
  "createdAt": "回應字串",
  "lastUsedAt": "回應字串",
  "member": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "createdByName": "回應字串",
  "revokedAt": "回應字串",
  "revokedByName": "回應字串",
  "gatewayAllowedLlmIds": [
    "550e8400-e29b-41d4-a716-446655440000"
  ]
}
```

***

### 撤銷 API Key <a href="#organizations-api-keys-destroy" id="organizations-api-keys-destroy"></a>

DELETE `/api/v1/organizations/{organizationPk}/api-keys/{id}/`

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `id`             | ✅  | string |                                      |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.delete(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->delete("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/api-keys/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

| 狀態碼 | 說明           |
| --- | ------------ |
| 204 | API Key 撤銷成功 |
| 400 | API Key 已被撤銷 |
| 403 | 權限不足         |
| 404 | 找不到 API Key  |

***

### 查詢 API Key 所屬組織 <a href="#users-api-key-context-retrieve" id="users-api-key-context-retrieve"></a>

GET `/api/v1/users/api-key-context/`

{% hint style="info" %}
只接受 `Authorization: Api-Key`，回傳金鑰綁定的組織；不計入金鑰的 RPM 額度。用途見 [共通規範：確認金鑰所屬的組織](https://docs.maiagent.ai/api/preparation/conventions#api-key-context)。
{% endhint %}

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/users/api-key-context/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/users/api-key-context/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/users/api-key-context/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/users/api-key-context/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "organizationId": string (uuid)
}
```

**回應範例值**

```json
{
  "organizationId": "550e8400-e29b-41d4-a716-446655440000"
}
```

**狀態碼: 401 - 缺少或無效的 API Key，或使用非 API Key 憑證**

***

### 換發成員嵌入 token <a href="#members-embed-tokens-create" id="members-embed-tokens-create"></a>

POST `/api/v1/members/embed-tokens/`

{% hint style="info" %}
以組織 API Key 為指定成員換發 15 分鐘效期的 token，供您的系統以成員身分嵌入 MaiGPT；只有組織擁有者或具「組織總覽」管理權限的成員持有的金鑰可呼叫。流程見技術手冊 [MaiGPT 成員身分嵌入](https://docs.maiagent.ai/tech/work/maigpt-integration)。
{% endhint %}

#### 請求內容

**請求參數**

| 欄位       | 類型             | 必填 | 說明 |
| -------- | -------------- | -- | -- |
| email    | string (email) | 否  |    |
| memberId | string (uuid)  | 否  |    |

**請求結構範例**

```typescript
{
  "email"?: string (email) // 非必填
  "memberId"?: string (uuid) // 非必填
}
```

**請求範例值**

```json
{
  "email": "user@example.com",
  "memberId": "550e8400-e29b-41d4-a716-446655440000"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/members/embed-tokens/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "memberId": "550e8400-e29b-41d4-a716-446655440000"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "email": "user@example.com",
    "memberId": "550e8400-e29b-41d4-a716-446655440000"
  };

axios.post("https://api.maiagent.ai/api/v1/members/embed-tokens/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/members/embed-tokens/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "email": "user@example.com",
    "memberId": "550e8400-e29b-41d4-a716-446655440000"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/members/embed-tokens/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'email' => 'user@example.com',
            'memberId' => '550e8400-e29b-41d4-a716-446655440000'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "accessToken": string
  "organizationId": string (uuid)
  "expiresAt": string (timestamp)
  "member": {
  {
    "id": string (uuid)
    "userId": string (uuid)
    "email": string (email)
    "name": string
  }
  }
}
```

**回應範例值**

```json
{
  "accessToken": "回應字串",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "expiresAt": "回應字串",
  "member": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "email": "response@example.com",
    "name": "回應字串"
  }
}
```

**狀態碼: 400 - email 與 memberId 必須且只能提供其中一個**

**狀態碼: 401 - 未以 Api-Key 認證**

**狀態碼: 403 - API Key 持有者不是組織擁有者也沒有組織管理權限**

**狀態碼: 404 - 指定的成員不存在、已停用或不屬於本組織**

***

### 列出 OAuth 應用程式 <a href="#oauth-applications-list" id="oauth-applications-list"></a>

GET `/api/v1/oauth/applications/`

{% hint style="info" %}
MaiAgent 作為 OAuth 2.1 授權伺服器時，您的應用程式先在此註冊。流程見技術手冊 [MaiAgent 作為 OAuth 授權伺服器](https://docs.maiagent.ai/tech/authorization-integration/maiagent-oauth-server)。
{% endhint %}

#### 參數

| 參數名稱       | 必填 | 類型      | 說明                                             |
| ---------- | -- | ------- | ---------------------------------------------- |
| `page`     | ❌  | integer | A page number within the paginated result set. |
| `pageSize` | ❌  | integer | Number of results to return per page.          |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/oauth/applications/?page=1&pageSize=1" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/oauth/applications/?page=1&pageSize=1", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/oauth/applications/?page=1&pageSize=1"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/oauth/applications/?page=1&pageSize=1", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "id": string (uuid)
      "name": string
      "clientId": string
      "clientType": 
      {
      }
      "redirectUris": [
        string
      ]
      "authorizedUserCount": integer
      "createdByName": string
      "created": string (timestamp)
      "updated": string (timestamp)
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應字串",
      "clientId": "回應字串",
      "clientType": {},
      "redirectUris": [
        "回應字串"
      ],
      "authorizedUserCount": 456,
      "createdByName": "回應字串",
      "created": "回應字串",
      "updated": "回應字串"
    }
  ]
}
```

***

### 註冊 OAuth 應用程式 <a href="#oauth-applications-create" id="oauth-applications-create"></a>

POST `/api/v1/oauth/applications/`

#### 請求內容

**請求參數**

| 欄位           | 類型             | 必填 | 說明 |
| ------------ | -------------- | -- | -- |
| name         | string         | 是  |    |
| clientType   | object         | 否  |    |
| redirectUris | array\[string] | 是  |    |

**請求結構範例**

```typescript
{
  "name": string
  "clientType"?:  // 非必填
  {
  }
  "redirectUris": [
    string
  ]
}
```

**請求範例值**

```json
{
  "name": "範例名稱",
  "clientType": {},
  "redirectUris": [
    "範例字串"
  ]
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/oauth/applications/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "範例名稱",
    "clientType": {},
    "redirectUris": [
      "範例字串"
    ]
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "name": "範例名稱",
    "clientType": {},
    "redirectUris": [
      "範例字串"
    ]
  };

axios.post("https://api.maiagent.ai/api/v1/oauth/applications/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/oauth/applications/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "name": "範例名稱",
    "clientType": {},
    "redirectUris": [
        "範例字串"
    ]
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/oauth/applications/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'name' => '範例名稱',
            'clientType' => new \stdClass(),
            'redirectUris' => [
                '範例字串'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "clientId": string
  "clientType": 
  {
  }
  "redirectUris": [
    string
  ]
  "authorizedUserCount": integer
  "createdByName": string
  "created": string (timestamp)
  "updated": string (timestamp)
  "clientSecret": string
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "clientId": "回應字串",
  "clientType": {},
  "redirectUris": [
    "回應字串"
  ],
  "authorizedUserCount": 456,
  "createdByName": "回應字串",
  "created": "回應字串",
  "updated": "回應字串",
  "clientSecret": "回應字串"
}
```

***

### 取得特定 OAuth 應用程式 <a href="#oauth-applications-retrieve" id="oauth-applications-retrieve"></a>

GET `/api/v1/oauth/applications/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                                         |
| ---- | -- | ------ | ---------------------------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this MaiAgent OAuth application. |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "clientId": string
  "clientType": 
  {
  }
  "redirectUris": [
    string
  ]
  "authorizedUserCount": integer
  "createdByName": string
  "created": string (timestamp)
  "updated": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "clientId": "回應字串",
  "clientType": {},
  "redirectUris": [
    "回應字串"
  ],
  "authorizedUserCount": 456,
  "createdByName": "回應字串",
  "created": "回應字串",
  "updated": "回應字串"
}
```

***

### 更新 OAuth 應用程式 <a href="#oauth-applications-partial-update" id="oauth-applications-partial-update"></a>

PATCH `/api/v1/oauth/applications/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                                         |
| ---- | -- | ------ | ---------------------------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this MaiAgent OAuth application. |

#### 請求內容

**請求參數**

| 欄位           | 類型             | 必填 | 說明 |
| ------------ | -------------- | -- | -- |
| name         | string         | 否  |    |
| redirectUris | array\[string] | 否  |    |

**請求結構範例**

```typescript
{
  "name"?: string // 非必填
  "redirectUris"?: [ // 非必填
    string
  ]
}
```

**請求範例值**

```json
{
  "name": "範例名稱",
  "redirectUris": [
    "範例字串"
  ]
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PATCH "https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "範例名稱",
    "redirectUris": [
      "範例字串"
    ]
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "name": "範例名稱",
    "redirectUris": [
      "範例字串"
    ]
  };

axios.patch("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "name": "範例名稱",
    "redirectUris": [
        "範例字串"
    ]
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->patch("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'name' => '範例名稱',
            'redirectUris' => [
                '範例字串'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "clientId": string
  "clientType": 
  {
  }
  "redirectUris": [
    string
  ]
  "authorizedUserCount": integer
  "createdByName": string
  "created": string (timestamp)
  "updated": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "clientId": "回應字串",
  "clientType": {},
  "redirectUris": [
    "回應字串"
  ],
  "authorizedUserCount": 456,
  "createdByName": "回應字串",
  "created": "回應字串",
  "updated": "回應字串"
}
```

***

### 刪除 OAuth 應用程式並撤銷其 token <a href="#oauth-applications-destroy" id="oauth-applications-destroy"></a>

DELETE `/api/v1/oauth/applications/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                                         |
| ---- | -- | ------ | ---------------------------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this MaiAgent OAuth application. |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.delete(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->delete("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

| 狀態碼 | 說明               |
| --- | ---------------- |
| 204 | No response body |

***

### 重新產生 client secret <a href="#oauth-applications-regenerate-secret-create" id="oauth-applications-regenerate-secret-create"></a>

POST `/api/v1/oauth/applications/{id}/regenerate-secret/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                                         |
| ---- | -- | ------ | ---------------------------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this MaiAgent OAuth application. |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/regenerate-secret/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.post("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/regenerate-secret/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/regenerate-secret/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.post(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/regenerate-secret/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "clientId": string
  "clientType": 
  {
  }
  "redirectUris": [
    string
  ]
  "authorizedUserCount": integer
  "createdByName": string
  "created": string (timestamp)
  "updated": string (timestamp)
  "clientSecret": string
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "clientId": "回應字串",
  "clientType": {},
  "redirectUris": [
    "回應字串"
  ],
  "authorizedUserCount": 456,
  "createdByName": "回應字串",
  "created": "回應字串",
  "updated": "回應字串",
  "clientSecret": "回應字串"
}
```

***

### 列出我授權過的 OAuth 應用程式 <a href="#oauth-authorized-applications-list" id="oauth-authorized-applications-list"></a>

GET `/api/v1/oauth/authorized-applications/`

#### 參數

| 參數名稱       | 必填 | 類型      | 說明                                             |
| ---------- | -- | ------- | ---------------------------------------------- |
| `page`     | ❌  | integer | A page number within the paginated result set. |
| `pageSize` | ❌  | integer | Number of results to return per page.          |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/oauth/authorized-applications/?page=1&pageSize=1" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/oauth/authorized-applications/?page=1&pageSize=1", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/oauth/authorized-applications/?page=1&pageSize=1"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/oauth/authorized-applications/?page=1&pageSize=1", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "id": string (uuid)
      "name": string
      "organization": string (uuid)
      "organizationName": string
      "tokenCount": integer
      "lastAuthorizedAt": string (timestamp)
      "latestExpiresAt": string (timestamp)
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應字串",
      "organization": "550e8400-e29b-41d4-a716-446655440000",
      "organizationName": "回應字串",
      "tokenCount": 456,
      "lastAuthorizedAt": "回應字串",
      "latestExpiresAt": "回應字串"
    }
  ]
}
```

***

### 撤銷我對某應用程式的授權 <a href="#oauth-authorized-applications-destroy" id="oauth-authorized-applications-destroy"></a>

DELETE `/api/v1/oauth/authorized-applications/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明 |
| ---- | -- | ------ | -- |
| `id` | ✅  | string |    |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/oauth/authorized-applications/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/oauth/authorized-applications/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/oauth/authorized-applications/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.delete(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->delete("https://api.maiagent.ai/api/v1/oauth/authorized-applications/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

| 狀態碼 | 說明               |
| --- | ---------------- |
| 204 | No response body |

***

### 刪除組織 <a href="#organizations-destroy" id="organizations-destroy"></a>

DELETE `/api/v1/organizations/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                 |
| ---- | -- | ------ | ---------------------------------- |
| `id` | ✅  | string | A UUID string identifying this 組織. |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.delete(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->delete("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

| 狀態碼 | 說明               |
| --- | ---------------- |
| 204 | No response body |

***

### 刪除指定成員 <a href="#organizations-members-destroy" id="organizations-members-destroy"></a>

DELETE `/api/v1/organizations/{organizationPk}/members/{id}/`

#### 參數

| 參數名稱             | 必填 | 類型     | 說明                                   |
| ---------------- | -- | ------ | ------------------------------------ |
| `id`             | ✅  | string | A UUID string identifying this 成員.   |
| `organizationPk` | ✅  | string | A UUID string identifying this 組織 ID |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.delete(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->delete("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/members/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

| 狀態碼 | 說明               |
| --- | ---------------- |
| 204 | No response body |

***

### 取得成員使用統計 <a href="#organizations-usage-statistics-members-list" id="organizations-usage-statistics-members-list"></a>

GET `/api/v1/organizations/{organizationPk}/usage-statistics/members/`

#### 參數

| 參數名稱              | 必填 | 類型      | 說明                                                                         |
| ----------------- | -- | ------- | -------------------------------------------------------------------------- |
| `organizationPk`  | ✅  | string  | A UUID string identifying this 組織 ID                                       |
| `chatbot`         | ❌  | string  | 篩選特定 AI 助理 ID                                                              |
| `chatbotId`       | ❌  | string  |                                                                            |
| `endDate`         | ❌  | string  | 結束日期，格式: YYYY-MM-DD                                                        |
| `includeTime`     | ❌  | boolean | 是否返回只按時間聚合的時間序列資料，用於趨勢圖表（true/false）。設為 true 時，回應不包含實體資訊，只有時間欄位和統計數值，且不分頁。 |
| `memberId`        | ❌  | string  |                                                                            |
| `page`            | ❌  | integer | 頁碼                                                                         |
| `pageSize`        | ❌  | integer | 每頁筆數                                                                       |
| `search`          | ❌  | string  | 搜尋成員 ID、名稱或 Email                                                          |
| `sortBy`          | ❌  | string  | 排序欄位                                                                       |
| `sortOrder`       | ❌  | string  | 排序方式 (asc/desc)                                                            |
| `startDate`       | ✅  | string  | 開始日期，格式: YYYY-MM-DD                                                        |
| `timeGranularity` | ❌  | string  | 時間粒度 (hour/day/month)                                                      |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/members/?chatbot=example&chatbotId=550e8400-e29b-41d4-a716-446655440000&endDate=example&includeTime=true&memberId=550e8400-e29b-41d4-a716-446655440000&page=1&pageSize=1&search=example&sortBy=conversations_count&sortOrder=asc&startDate=example&timeGranularity=day" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/members/?chatbot=example&chatbotId=550e8400-e29b-41d4-a716-446655440000&endDate=example&includeTime=true&memberId=550e8400-e29b-41d4-a716-446655440000&page=1&pageSize=1&search=example&sortBy=conversations_count&sortOrder=asc&startDate=example&timeGranularity=day", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/members/?chatbot=example&chatbotId=550e8400-e29b-41d4-a716-446655440000&endDate=example&includeTime=true&memberId=550e8400-e29b-41d4-a716-446655440000&page=1&pageSize=1&search=example&sortBy=conversations_count&sortOrder=asc&startDate=example&timeGranularity=day"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/members/?chatbot=example&chatbotId=550e8400-e29b-41d4-a716-446655440000&endDate=example&includeTime=true&memberId=550e8400-e29b-41d4-a716-446655440000&page=1&pageSize=1&search=example&sortBy=conversations_count&sortOrder=asc&startDate=example&timeGranularity=day", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "count"?: integer // 結果數量 (非必填)
      "results"?: [ // 非必填
        {
          "member"?: { // 非必填
          {
            "id"?: string (uuid) // 成員 ID (非必填)
            "name"?: string // 成員名稱 (非必填)
            "email"?: string // 成員電子郵件 (非必填)
          }
          }
          "datetime"?: string (date-time) // 時間戳（僅 include_time=true 且 time_granularity=hour 時出現） (非必填)
          "period"?: string (date) // 日期（僅 include_time=true 且 time_granularity=day/month 時出現） (非必填)
          "input_characters_count"?: integer // 輸入字元數 (非必填)
          "output_characters_count"?: integer // 輸出字元數 (非必填)
          "input_token_usage"?: integer // 輸入 Token 數 (非必填)
          "output_token_usage"?: integer // 輸出 Token 數 (非必填)
          "messages_count"?: integer // 訊息數 (非必填)
          "conversations_count"?: integer // 對話數 (非必填)
          "total_characters_count"?: integer // 總字元數 (非必填)
          "total_token_usage"?: integer // 總 Token 數 (非必填)
        }
      ]
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "count": 2,
      "results": [
        {
          "member": {
            "id": "3a245511-d5e0-4e06-9dc6-1106915b9a8a",
            "name": "王小明",
            "email": "wang@example.com"
          },
          "input_characters_count": 10000,
          "output_characters_count": 15000,
          "input_token_usage": 2500,
          "output_token_usage": 3750,
          "messages_count": 100,
          "conversations_count": 50,
          "total_characters_count": 25000,
          "total_token_usage": 6250
        }
      ]
    }
  ]
}
```

***

### 取得成員使用統計摘要 <a href="#organizations-usage-statistics-members-summary-retrieve" id="organizations-usage-statistics-members-summary-retrieve"></a>

GET `/api/v1/organizations/{organizationPk}/usage-statistics/members/summary/`

#### 參數

| 參數名稱              | 必填 | 類型     | 說明                                   |
| ----------------- | -- | ------ | ------------------------------------ |
| `organizationPk`  | ✅  | string | A UUID string identifying this 組織 ID |
| `endDate`         | ❌  | string | 結束日期，格式: YYYY-MM-DD                  |
| `startDate`       | ✅  | string | 開始日期，格式: YYYY-MM-DD                  |
| `timeGranularity` | ❌  | string | 時間粒度 (hour/day/month)                |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/members/summary/?endDate=example&startDate=example&timeGranularity=day" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/members/summary/?endDate=example&startDate=example&timeGranularity=day", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/members/summary/?endDate=example&startDate=example&timeGranularity=day"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/members/summary/?endDate=example&startDate=example&timeGranularity=day", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "totalInputCharacters"?: integer // 總輸入字元數 (非必填)
  "totalOutputCharacters"?: integer // 總輸出字元數 (非必填)
  "totalCharacters"?: integer // 總字元數 (非必填)
  "totalInputTokens"?: integer // 總輸入 Token 數 (非必填)
  "totalOutputTokens"?: integer // 總輸出 Token 數 (非必填)
  "totalTokens"?: integer // 總 Token 數 (非必填)
  "totalMessages"?: integer // 總訊息數 (非必填)
  "totalConversations"?: integer // 總對話數 (非必填)
  "chatbotScope"?: string (enum: organization, accessible_chatbots) // 呼叫者的用量統計範圍：organization＝全組織；accessible_chatbots＝僅所屬角色被授權的 AI 助理 (非必填)
  "totalCount"?: integer // 符合查詢條件的每小時成員統計筆數：同一成員在不同小時、不同 AI 助理各算一筆，不是成員數 (非必填)
}
```

**回應範例值**

```json
{
  "totalInputCharacters": 456,
  "totalOutputCharacters": 456,
  "totalCharacters": 456,
  "totalInputTokens": 456,
  "totalOutputTokens": 456,
  "totalTokens": 456,
  "totalMessages": 456,
  "totalConversations": 456,
  "chatbotScope": "organization",
  "totalCount": 456
}
```

***

### 取得 AI 助理使用統計 <a href="#organizations-usage-statistics-chatbots-list" id="organizations-usage-statistics-chatbots-list"></a>

GET `/api/v1/organizations/{organizationPk}/usage-statistics/chatbots/`

#### 參數

| 參數名稱              | 必填 | 類型      | 說明                                                                         |
| ----------------- | -- | ------- | -------------------------------------------------------------------------- |
| `organizationPk`  | ✅  | string  | A UUID string identifying this 組織 ID                                       |
| `chatbotId`       | ❌  | string  |                                                                            |
| `endDate`         | ❌  | string  | 結束日期，格式: YYYY-MM-DD                                                        |
| `includeTime`     | ❌  | boolean | 是否返回只按時間聚合的時間序列資料，用於趨勢圖表（true/false）。設為 true 時，回應不包含實體資訊，只有時間欄位和統計數值，且不分頁。 |
| `page`            | ❌  | integer | 頁碼                                                                         |
| `pageSize`        | ❌  | integer | 每頁筆數                                                                       |
| `search`          | ❌  | string  | 搜尋 AI 助理 ID 或名稱                                                            |
| `sortBy`          | ❌  | string  | 排序欄位                                                                       |
| `sortOrder`       | ❌  | string  | 排序方式 (asc/desc)                                                            |
| `startDate`       | ✅  | string  | 開始日期，格式: YYYY-MM-DD                                                        |
| `timeGranularity` | ❌  | string  | 時間粒度 (hour/day/month)                                                      |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/chatbots/?chatbotId=550e8400-e29b-41d4-a716-446655440000&endDate=example&includeTime=true&page=1&pageSize=1&search=example&sortBy=conversations_count&sortOrder=asc&startDate=example&timeGranularity=day" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/chatbots/?chatbotId=550e8400-e29b-41d4-a716-446655440000&endDate=example&includeTime=true&page=1&pageSize=1&search=example&sortBy=conversations_count&sortOrder=asc&startDate=example&timeGranularity=day", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/chatbots/?chatbotId=550e8400-e29b-41d4-a716-446655440000&endDate=example&includeTime=true&page=1&pageSize=1&search=example&sortBy=conversations_count&sortOrder=asc&startDate=example&timeGranularity=day"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/chatbots/?chatbotId=550e8400-e29b-41d4-a716-446655440000&endDate=example&includeTime=true&page=1&pageSize=1&search=example&sortBy=conversations_count&sortOrder=asc&startDate=example&timeGranularity=day", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "count"?: integer // 結果數量 (非必填)
      "results"?: [ // 非必填
        {
          "chatbot"?: { // 非必填
          {
            "id"?: string (uuid) // AI 助理 ID (非必填)
            "name"?: string // AI 助理名稱 (非必填)
          }
          }
          "datetime"?: string (date-time) // 時間戳（僅 include_time=true 且 time_granularity=hour 時出現） (非必填)
          "period"?: string (date) // 日期（僅 include_time=true 且 time_granularity=day/month 時出現） (非必填)
          "input_characters_count"?: integer // 輸入字元數 (非必填)
          "output_characters_count"?: integer // 輸出字元數 (非必填)
          "input_token_usage"?: integer // 輸入 Token 數 (非必填)
          "output_token_usage"?: integer // 輸出 Token 數 (非必填)
          "messages_count"?: integer // 訊息數 (非必填)
          "conversations_count"?: integer // 對話數 (非必填)
          "total_characters_count"?: integer // 總字元數 (非必填)
          "total_token_usage"?: integer // 總 Token 數 (非必填)
        }
      ]
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "count": 2,
      "results": [
        {
          "chatbot": {
            "id": "5b646600-f6e0-4f07-aec7-0207a26c0a9b",
            "name": "客服助理"
          },
          "input_characters_count": 10000,
          "output_characters_count": 15000,
          "input_token_usage": 2500,
          "output_token_usage": 3750,
          "messages_count": 100,
          "conversations_count": 50,
          "total_characters_count": 25000,
          "total_token_usage": 6250
        }
      ]
    }
  ]
}
```

***

### 取得 AI 助理使用統計摘要 <a href="#organizations-usage-statistics-chatbots-summary-retrieve" id="organizations-usage-statistics-chatbots-summary-retrieve"></a>

GET `/api/v1/organizations/{organizationPk}/usage-statistics/chatbots/summary/`

#### 參數

| 參數名稱              | 必填 | 類型     | 說明                                   |
| ----------------- | -- | ------ | ------------------------------------ |
| `organizationPk`  | ✅  | string | A UUID string identifying this 組織 ID |
| `endDate`         | ❌  | string | 結束日期，格式: YYYY-MM-DD                  |
| `startDate`       | ✅  | string | 開始日期，格式: YYYY-MM-DD                  |
| `timeGranularity` | ❌  | string | 時間粒度 (hour/day/month)                |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/chatbots/summary/?endDate=example&startDate=example&timeGranularity=day" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/chatbots/summary/?endDate=example&startDate=example&timeGranularity=day", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/chatbots/summary/?endDate=example&startDate=example&timeGranularity=day"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/usage-statistics/chatbots/summary/?endDate=example&startDate=example&timeGranularity=day", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "totalInputCharacters"?: integer // 總輸入字元數 (非必填)
  "totalOutputCharacters"?: integer // 總輸出字元數 (非必填)
  "totalCharacters"?: integer // 總字元數 (非必填)
  "totalInputTokens"?: integer // 總輸入 Token 數 (非必填)
  "totalOutputTokens"?: integer // 總輸出 Token 數 (非必填)
  "totalTokens"?: integer // 總 Token 數 (非必填)
  "totalMessages"?: integer // 總訊息數 (非必填)
  "totalConversations"?: integer // 總對話數 (非必填)
  "chatbotScope"?: string (enum: organization, accessible_chatbots) // 呼叫者的用量統計範圍：organization＝全組織；accessible_chatbots＝僅所屬角色被授權的 AI 助理 (非必填)
  "totalChatbots"?: integer // 查詢期間內有使用紀錄的 AI 助理數（去重）；期間內沒有使用的不計入，不是組織的 AI 助理總數 (非必填)
}
```

**回應範例值**

```json
{
  "totalInputCharacters": 456,
  "totalOutputCharacters": 456,
  "totalCharacters": 456,
  "totalInputTokens": 456,
  "totalOutputTokens": 456,
  "totalTokens": 456,
  "totalMessages": 456,
  "totalConversations": 456,
  "chatbotScope": "organization",
  "totalChatbots": 456
}
```

***

### 列出自己的記憶 <a href="#me-memories-list" id="me-memories-list"></a>

GET `/api/v1/me/memories/`

{% hint style="info" %}
請帶 `X-Organization-Id` 標頭指定要操作的組織，以 API 金鑰呼叫時也要帶。可用 `status`（`active`／`expired`）、`kind`（`fact`／`preference`／`instruction`）查詢參數篩選；待確認或被拒絕的記憶不會列出。行為說明見技術手冊[成員記憶管理 API](https://docs.maiagent.ai/tech/api-integration/endpoint-behaviors/member-memory-api)。
{% endhint %}

#### 參數

| 參數名稱       | 必填 | 類型      | 說明                                                                                                                        |
| ---------- | -- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| `kind`     | ❌  | string  | \`fact\`: Fact ; \`preference\`: Preference ; \`instruction\`: Instruction ; \`summary\`: Summary ; \`profile\`: Profile; |
| `page`     | ❌  | integer | A page number within the paginated result set.                                                                            |
| `pageSize` | ❌  | integer | Number of results to return per page.                                                                                     |
| `status`   | ❌  | string  | \`pending\`: Pending ; \`active\`: Active ; \`rejected\`: Rejected ; \`expired\`: Expired;                                |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/me/memories/?kind=fact&page=1&pageSize=1&status=active" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/me/memories/?kind=fact&page=1&pageSize=1&status=active", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/me/memories/?kind=fact&page=1&pageSize=1&status=active"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/me/memories/?kind=fact&page=1&pageSize=1&status=active", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "id": string (uuid)
      "topic": string // LLM-assigned topic slug for grouping related memories (e.g. "language_preferences", "role", "communication_style"). Null means legacy memory without topic grouping.
      "category": // 可能有不同的類型
      string (enum: personal_info, work_role, projects, communication, response_format, tools_tech, interests, health_lifestyle, schedule_plans, other) // Fixed category shown to users. Null means legacy memory without a category.

* `personal_info` - Personal Info
* `work_role` - Work and Role
* `projects` - Projects and Work
* `communication` - Communication Preferences
* `response_format` - Response Format Preferences
* `tools_tech` - Tools and Technology
* `interests` - Interests and Hobbies
* `health_lifestyle` - Health and Lifestyle
* `schedule_plans` - Schedule and Plans
* `other` - Other
      "categoryDisplay": string // Translated category name.
      "summary": string // One-line summary of the memory topic.
      "details": object // Concrete facts for this topic, stored as a list of strings.
      "kind": 
      {
      }
      "source":  // How this memory was created: user explicitly stated, agent extracted, or manually added.

* `user_stated` - User Stated
* `agent_extracted` - Agent Extracted
* `agent_stated` - Agent Stated
* `user_manual` - User Manual
      {
      }
      "requestedByUser": boolean // True when the user explicitly asked the agent to remember this. Only affects the UI label (S12), not LRU eviction priority (S6).
      "status": 
      {
      }
      "createdAt": string (timestamp)
      "updatedAt": string (timestamp)
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "topic": "回應字串",
      "category": "personal_info",
      "categoryDisplay": "回應字串",
      "summary": "回應字串",
      "details": null,
      "kind": {},
      "source": {},
      "requestedByUser": false,
      "status": {},
      "createdAt": "回應字串",
      "updatedAt": "回應字串"
    }
  ]
}
```

***

### 建立或更新自己的記憶 <a href="#me-memories-create" id="me-memories-create"></a>

POST `/api/v1/me/memories/`

{% hint style="info" %}
請帶 `X-Organization-Id` 標頭指定要操作的組織，以 API 金鑰呼叫時也要帶。請求欄位：`topic`（必填，最多 100 字元，只能用小寫英文字母、數字與中間的底線）、`summary`（必填，最多 500 字元）、`details`（必填，字串陣列，最多 20 項、每項最多 500 字元）、`kind`（`fact`／`preference`／`instruction`，預設 `fact`）。同一成員已有相同 `topic` 的啟用中記憶時更新該筆並回 200，新建回 201。
{% endhint %}

#### 請求內容

**請求參數**

| 欄位       | 類型                                                                                                                                                      | 必填 | 說明                                                                                                                                                                                                          |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| topic    | string                                                                                                                                                  | 是  |                                                                                                                                                                                                             |
| category | string (enum: personal\_info, work\_role, projects, communication, response\_format, tools\_tech, interests, health\_lifestyle, schedule\_plans, other) | 否  | `personal_info`: Personal Info ; `work_role`: Work and Role ; `projects`: Projects and Work ; `communication`: Communication Preferences ; `response_format`: Response Format Preferences ; `tools_tech`... |
| summary  | string                                                                                                                                                  | 是  |                                                                                                                                                                                                             |
| details  | array\[string]                                                                                                                                          | 是  |                                                                                                                                                                                                             |
| kind     | object                                                                                                                                                  | 否  |                                                                                                                                                                                                             |

**請求結構範例**

```typescript
{
  "topic": string
  "category"?: string (enum: personal_info, work_role, projects, communication, response_format, tools_tech, interests, health_lifestyle, schedule_plans, other) // * `personal_info` - Personal Info
* `work_role` - Work and Role
* `projects` - Projects and Work
* `communication` - Communication Preferences
* `response_format` - Response Format Preferences
* `tools_tech` - Tools and Technology
* `interests` - Interests and Hobbies
* `health_lifestyle` - Health and Lifestyle
* `schedule_plans` - Schedule and Plans
* `other` - Other (非必填)
  "summary": string
  "details": [
    string
  ]
  "kind"?:  // 非必填
  {
  }
}
```

**請求範例值**

```json
{
  "topic": "範例字串",
  "category": "personal_info",
  "summary": "範例字串",
  "details": [
    "範例字串"
  ],
  "kind": {}
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/me/memories/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "範例字串",
    "category": "personal_info",
    "summary": "範例字串",
    "details": [
      "範例字串"
    ],
    "kind": {}
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "topic": "範例字串",
    "category": "personal_info",
    "summary": "範例字串",
    "details": [
      "範例字串"
    ],
    "kind": {}
  };

axios.post("https://api.maiagent.ai/api/v1/me/memories/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/me/memories/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "topic": "範例字串",
    "category": "personal_info",
    "summary": "範例字串",
    "details": [
        "範例字串"
    ],
    "kind": {}
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/me/memories/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'topic' => '範例字串',
            'category' => 'personal_info',
            'summary' => '範例字串',
            'details' => [
                '範例字串'
            ],
            'kind' => new \stdClass()
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "topic": string // LLM-assigned topic slug for grouping related memories (e.g. "language_preferences", "role", "communication_style"). Null means legacy memory without topic grouping.
  "category": // 可能有不同的類型
  string (enum: personal_info, work_role, projects, communication, response_format, tools_tech, interests, health_lifestyle, schedule_plans, other) // Fixed category shown to users. Null means legacy memory without a category.

* `personal_info` - Personal Info
* `work_role` - Work and Role
* `projects` - Projects and Work
* `communication` - Communication Preferences
* `response_format` - Response Format Preferences
* `tools_tech` - Tools and Technology
* `interests` - Interests and Hobbies
* `health_lifestyle` - Health and Lifestyle
* `schedule_plans` - Schedule and Plans
* `other` - Other
  "categoryDisplay": string // Translated category name.
  "summary": string // One-line summary of the memory topic.
  "details": object // Concrete facts for this topic, stored as a list of strings.
  "kind": 
  {
  }
  "source":  // How this memory was created: user explicitly stated, agent extracted, or manually added.

* `user_stated` - User Stated
* `agent_extracted` - Agent Extracted
* `agent_stated` - Agent Stated
* `user_manual` - User Manual
  {
  }
  "requestedByUser": boolean // True when the user explicitly asked the agent to remember this. Only affects the UI label (S12), not LRU eviction priority (S6).
  "status": 
  {
  }
  "createdAt": string (timestamp)
  "updatedAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "topic": "回應字串",
  "category": "personal_info",
  "categoryDisplay": "回應字串",
  "summary": "回應字串",
  "details": null,
  "kind": {},
  "source": {},
  "requestedByUser": false,
  "status": {},
  "createdAt": "回應字串",
  "updatedAt": "回應字串"
}
```

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "topic": string // LLM-assigned topic slug for grouping related memories (e.g. "language_preferences", "role", "communication_style"). Null means legacy memory without topic grouping.
  "category": // 可能有不同的類型
  string (enum: personal_info, work_role, projects, communication, response_format, tools_tech, interests, health_lifestyle, schedule_plans, other) // Fixed category shown to users. Null means legacy memory without a category.

* `personal_info` - Personal Info
* `work_role` - Work and Role
* `projects` - Projects and Work
* `communication` - Communication Preferences
* `response_format` - Response Format Preferences
* `tools_tech` - Tools and Technology
* `interests` - Interests and Hobbies
* `health_lifestyle` - Health and Lifestyle
* `schedule_plans` - Schedule and Plans
* `other` - Other
  "categoryDisplay": string // Translated category name.
  "summary": string // One-line summary of the memory topic.
  "details": object // Concrete facts for this topic, stored as a list of strings.
  "kind": 
  {
  }
  "source":  // How this memory was created: user explicitly stated, agent extracted, or manually added.

* `user_stated` - User Stated
* `agent_extracted` - Agent Extracted
* `agent_stated` - Agent Stated
* `user_manual` - User Manual
  {
  }
  "requestedByUser": boolean // True when the user explicitly asked the agent to remember this. Only affects the UI label (S12), not LRU eviction priority (S6).
  "status": 
  {
  }
  "createdAt": string (timestamp)
  "updatedAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "topic": "回應字串",
  "category": "personal_info",
  "categoryDisplay": "回應字串",
  "summary": "回應字串",
  "details": null,
  "kind": {},
  "source": {},
  "requestedByUser": false,
  "status": {},
  "createdAt": "回應字串",
  "updatedAt": "回應字串"
}
```

***

### 修改或重新啟用自己的記憶 <a href="#me-memories-partial-update" id="me-memories-partial-update"></a>

PATCH `/api/v1/me/memories/{id}/`

{% hint style="info" %}
請帶 `X-Organization-Id` 標頭指定要操作的組織，以 API 金鑰呼叫時也要帶。可帶 `topic`、`summary`、`details`（限制同建立）修改內容，或帶 `status`（`active`／`expired`）停用或重新啟用；至少要帶其中一個欄位。
{% endhint %}

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                           |
| ---- | -- | ------ | -------------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this Memory Entry. |

#### 請求內容

**請求參數**

| 欄位       | 類型                                                                                                                                                      | 必填 | 說明                                                                                                                                                                                                          |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| topic    | string                                                                                                                                                  | 否  |                                                                                                                                                                                                             |
| category | string (enum: personal\_info, work\_role, projects, communication, response\_format, tools\_tech, interests, health\_lifestyle, schedule\_plans, other) | 否  | `personal_info`: Personal Info ; `work_role`: Work and Role ; `projects`: Projects and Work ; `communication`: Communication Preferences ; `response_format`: Response Format Preferences ; `tools_tech`... |
| summary  | string                                                                                                                                                  | 否  |                                                                                                                                                                                                             |
| details  | array\[string]                                                                                                                                          | 否  |                                                                                                                                                                                                             |
| status   | string (enum: active, expired)                                                                                                                          | 否  | `active`: active ; `expired`: expired;                                                                                                                                                                      |

**請求結構範例**

```typescript
{
  "topic"?: string // 非必填
  "category"?: string (enum: personal_info, work_role, projects, communication, response_format, tools_tech, interests, health_lifestyle, schedule_plans, other) // * `personal_info` - Personal Info
* `work_role` - Work and Role
* `projects` - Projects and Work
* `communication` - Communication Preferences
* `response_format` - Response Format Preferences
* `tools_tech` - Tools and Technology
* `interests` - Interests and Hobbies
* `health_lifestyle` - Health and Lifestyle
* `schedule_plans` - Schedule and Plans
* `other` - Other (非必填)
  "summary"?: string // 非必填
  "details"?: [ // 非必填
    string
  ]
  "status"?: string (enum: active, expired) // * `active` - active
* `expired` - expired (非必填)
}
```

**請求範例值**

```json
{
  "topic": "範例字串",
  "category": "personal_info",
  "summary": "範例字串",
  "details": [
    "範例字串"
  ],
  "status": "active"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PATCH "https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "範例字串",
    "category": "personal_info",
    "summary": "範例字串",
    "details": [
      "範例字串"
    ],
    "status": "active"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "topic": "範例字串",
    "category": "personal_info",
    "summary": "範例字串",
    "details": [
      "範例字串"
    ],
    "status": "active"
  };

axios.patch("https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "topic": "範例字串",
    "category": "personal_info",
    "summary": "範例字串",
    "details": [
        "範例字串"
    ],
    "status": "active"
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->patch("https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'topic' => '範例字串',
            'category' => 'personal_info',
            'summary' => '範例字串',
            'details' => [
                '範例字串'
            ],
            'status' => 'active'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "topic": string // LLM-assigned topic slug for grouping related memories (e.g. "language_preferences", "role", "communication_style"). Null means legacy memory without topic grouping.
  "category": // 可能有不同的類型
  string (enum: personal_info, work_role, projects, communication, response_format, tools_tech, interests, health_lifestyle, schedule_plans, other) // Fixed category shown to users. Null means legacy memory without a category.

* `personal_info` - Personal Info
* `work_role` - Work and Role
* `projects` - Projects and Work
* `communication` - Communication Preferences
* `response_format` - Response Format Preferences
* `tools_tech` - Tools and Technology
* `interests` - Interests and Hobbies
* `health_lifestyle` - Health and Lifestyle
* `schedule_plans` - Schedule and Plans
* `other` - Other
  "categoryDisplay": string // Translated category name.
  "summary": string // One-line summary of the memory topic.
  "details": object // Concrete facts for this topic, stored as a list of strings.
  "kind": 
  {
  }
  "source":  // How this memory was created: user explicitly stated, agent extracted, or manually added.

* `user_stated` - User Stated
* `agent_extracted` - Agent Extracted
* `agent_stated` - Agent Stated
* `user_manual` - User Manual
  {
  }
  "requestedByUser": boolean // True when the user explicitly asked the agent to remember this. Only affects the UI label (S12), not LRU eviction priority (S6).
  "status": 
  {
  }
  "createdAt": string (timestamp)
  "updatedAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "topic": "回應字串",
  "category": "personal_info",
  "categoryDisplay": "回應字串",
  "summary": "回應字串",
  "details": null,
  "kind": {},
  "source": {},
  "requestedByUser": false,
  "status": {},
  "createdAt": "回應字串",
  "updatedAt": "回應字串"
}
```

***

### 刪除自己的記憶 <a href="#me-memories-destroy" id="me-memories-destroy"></a>

DELETE `/api/v1/me/memories/{id}/`

{% hint style="info" %}
請帶 `X-Organization-Id` 標頭指定要操作的組織，以 API 金鑰呼叫時也要帶。
{% endhint %}

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                           |
| ---- | -- | ------ | -------------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this Memory Entry. |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.delete(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->delete("https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

| 狀態碼 | 說明               |
| --- | ---------------- |
| 204 | No response body |

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.maiagent.ai/api/api-reference/zu-zhi-he-cheng-yuan.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
