> 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/en/api-reference/zu-zhi-he-cheng-yuan.md).

# Organizations and Members

### Register an Account <a href="#auth-registration-create" id="auth-registration-create"></a>

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

#### Request Body

**Request Parameters**

| Field         | Type                                     | Required | Description |
| ------------- | ---------------------------------------- | -------- | ----------- |
| email         | string (email)                           | Yes      |             |
| password1     | string                                   | Yes      |             |
| password2     | string                                   | Yes      |             |
| name          | string                                   | Yes      |             |
| company       | string                                   | Yes      |             |
| referralCode  | string                                   | No       |             |
| authSource    | object (contains 2 properties: id, name) | No       |             |
| authSource.id | string (uuid)                            | Yes      |             |

**Request Schema Example**

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

**Example Request Values**

```json
{
  "email": "user@example.com",
  "password1": "Example string",
  "password2": "Example string",
  "name": "Example name",
  "company": "Example string",
  "referralCode": "Example string",
  "authSource": {
    "id": "550e8400-e29b-41d4-a716-446655440000"
  }
}
```

#### Code Examples

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

```bash
# Example API call (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": "Example string",
    "password2": "Example string",
    "name": "Example name",
    "company": "Example string",
    "referralCode": "Example string",
    "authSource": {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "email": "user@example.com",
    "password1": "Example string",
    "password2": "Example string",
    "name": "Example name",
    "company": "Example string",
    "referralCode": "Example string",
    "authSource": {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  };

axios.post("https://api.maiagent.ai/api/v1/auth/registration/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

# Request Body (payload)
data = {
    "email": "user@example.com",
    "password1": "Example string",
    "password2": "Example string",
    "name": "Example name",
    "company": "Example string",
    "referralCode": "Example string",
    "authSource": {
        "id": "550e8400-e29b-41d4-a716-446655440000"
    }
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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' => 'Example string',
            'password2' => 'Example string',
            'name' => 'Example name',
            'company' => 'Example string',
            'referralCode' => 'Example string',
            'authSource' => [
                'id' => '550e8400-e29b-41d4-a716-446655440000'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 201**

**Response Schema Example**

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

**Example Response Values**

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

***

### Change Password <a href="#auth-password-change-create" id="auth-password-change-create"></a>

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

#### Request Body

**Request Parameters**

| Field        | Type   | Required | Description |
| ------------ | ------ | -------- | ----------- |
| oldPassword  | string | Yes      |             |
| newPassword1 | string | Yes      |             |
| newPassword2 | string | Yes      |             |

**Request Schema Example**

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

**Example Request Values**

```json
{
  "oldPassword": "Example string",
  "newPassword1": "Example string",
  "newPassword2": "Example string"
}
```

#### Code Examples

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

```bash
# Example API call (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": "Example string",
    "newPassword1": "Example string",
    "newPassword2": "Example string"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "oldPassword": "Example string",
    "newPassword1": "Example string",
    "newPassword2": "Example string"
  };

axios.post("https://api.maiagent.ai/api/v1/auth/password/change/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

# Request Body (payload)
data = {
    "oldPassword": "Example string",
    "newPassword1": "Example string",
    "newPassword2": "Example string"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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' => 'Example string',
            'newPassword1' => 'Example string',
            'newPassword2' => 'Example string'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

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

**Example Response Values**

```json
{
  "detail": "Response string"
}
```

***

### Create an organization <a href="#organizations-create" id="organizations-create"></a>

POST `/api/v1/organizations/`

#### Request body

**Request parameters**

| Field         | Type            | Required | Description                                                    |
| ------------- | --------------- | -------- | -------------------------------------------------------------- |
| name          | string          | Yes      | Organization name                                              |
| compact\_logo | string (binary) | No       | Compact logo (optional, available only on the Enterprise plan) |
| full\_logo    | string (binary) | No       | Full logo (optional, available only on the Enterprise plan)    |

**Example request schema**

```typescript
{
  "name": string // Organization name
  "compact_logo"?: string (binary) // Compact logo (optional, available only on the Enterprise plan) (Optional)
  "full_logo"?: string (binary) // Full logo (optional, available only on the Enterprise plan) (Optional)
}
```

**Example request values**

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

#### Code examples

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

```bash
# API call example (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"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request body (payload)
const data = {
    "name": "My Organization"
  };

axios.post("https://api.maiagent.ai/api/v1/organizations/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request body (payload)
data = {
    "name": "My Organization"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response body

**Status code: 201**

**Example response schema**

```typescript
{
  "id": string (uuid)
  "name": string
  "createdAt": string (timestamp)
  "compactLogo"?: string (uri) // Optional
  "fullLogo"?: string (uri) // Optional
  "themePrimaryColor"?: // May have different types (Optional)
  string // UI theme color for buttons, links, and other elements (HEX format, e.g. #0960bd); leave blank if unset to fall back to the system brand primary color (Optional)
  "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. (Optional)
  "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. (Optional)
  "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 // Whether the organization is in a trial period. True when the organization has exactly one trial plan and it is currently active
  "expirationDays": integer // Days since expiration. A positive number indicates days expired; null indicates a plan that has not expired or a permanent plan
  "showTrialBanner": boolean // Controls whether the frontend displays the trial/free plan banner
  "agentScheduleMinIntervalSeconds": integer // Minimum schedule execution interval in seconds, configured by the platform; the frontend displays this minimum when creating or editing schedules, while the schedule API enforces it
  "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. (Optional)
  "taxId"?: // May have different types (Optional)
  string // Applicant-reported business tax ID (8 digits, optional). Stored as-is; not verified. (Optional)
  "contactPhone"?: string // Applicant-reported contact phone collected at organization creation for approval review. (Optional)
  "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. (Optional)
  "invitationCode"?: string // Optional
  "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.
}
```

**Example response values**

```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": "Free plan",
    "planType": "free",
    "expiredAt": null
  },
  "maigptInboxId": null,
  "canUseCustomElasticsearch": false,
  "isTrial": true,
  "expirationDays": null
}
```

***

### Add a Member to the Specified Organization <a href="#organizations-members-create" id="organizations-members-create"></a>

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

#### Parameters

| Parameter Name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `organizationPk` | ✅        | string | A UUID string identifying this Organization ID |

#### Request Body

**Request Parameters**

| Field        | Type           | Required | Description |
| ------------ | -------------- | -------- | ----------- |
| email        | string (email) | Yes      |             |
| organization | string (uuid)  | No       |             |

**Request Schema Example**

```typescript
{
  "email": string (email)
  "organization"?: string (uuid) // Optional
}
```

**Example Request Values**

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

#### Code Examples

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

```bash
# Example API call (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
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

# Request Body (payload)
data = {
    "organization": "613c86f7-a45f-4e29-b255-29caff89de32",
    "is_owner": False
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 201**

**Response Schema Example**

```typescript
{
  "organization": string (uuid) // Organization ID
  "is_owner": boolean // Whether the member is the organization owner
}
```

**Example Response Values**

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

***

### Bulk Import Members <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" %}
Upload `file` (.xlsx) using `multipart/form-data`. The `Email(required)` column is required, and the `Name` column is optional. Each upload supports up to 25,000 rows (excluding the header). If this limit is exceeded, the entire file is rejected with `400`; split the file into smaller files for import. If any row has a blank or invalid Email, or a Name longer than 255 characters, the entire file is also rejected, and the `400` response's `detail` is an array of strings listing errors by row. If the `Email(required)` column is missing or the file has no data rows, `detail` is a single string. If the file is not .xlsx, the error is returned in the `file` field. When an Email appears more than once, only the first occurrence is processed. People whose Email is not yet in the organization are added and counted in `added`. Name becomes their name within the organization (if the account is also created during this import, Name is also used as the account name; if omitted, the Email prefix is used). For existing members, behavior depends on the importer's role: when the organization owner imports, a Name that differs from the current display name updates the member's name within the organization (`updated`); a blank or identical Name leaves it unchanged (`unchanged`); if Name differs but the member is managed through SCIM synchronization, the name is not updated (`scimSkipped`). For imports by non-owners, the existing behavior is preserved: existing members are skipped and their names are not updated (`skippedExisting`). `importerIsOwner` indicates whether the importer is the owner. Only names within the organization are updated; existing members' account names are not changed. `created` retains its original meaning: the total of newly added and existing members, equal to the sum of `added`, `updated`, `unchanged`, `scimSkipped`, and `skippedExisting`. Integrations that read only `created` require no changes. `message` contains messages for individual rows. For imports by the owner, “Already in the organization” is replaced with “Row N: Name updated”, “Row N: Unchanged”, or “Row N: Managed through SCIM synchronization; not updated”. For imports by non-owners, the original messages are preserved.
{% endhint %}

#### Parameters

| Parameter Name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `organizationPk` | ✅        | string | A UUID string identifying this organization ID |

#### Code Examples

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

```bash
# API call example (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Create a FormData object
const formData = new FormData();
// Replace with an actual file
formData.append('file', /* actual file object */, 'example_file.xlsx');

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

# Prepare the file and form data
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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status Code: 201**

**Example Response Schema**

```typescript
{
  "created": integer // Total number of members processed (including newly created and existing members)
  "added": integer // Number of members newly added to the organization
  "updated": integer // Number of existing members whose names within the organization were updated during an import by the owner
  "unchanged": integer // Number of existing members left unchanged during an import by the owner because Name was blank or matched the current display name
  "scimSkipped": integer // Number of existing members whose names were not updated during an import by the owner because they are managed through SCIM synchronization
  "skippedExisting": integer // Number of members skipped during an import by a non-owner because they are already in the organization; 0 for imports by the owner
  "importerIsOwner": boolean // Whether the importer is the organization owner
  "message"?: [ // Per-row messages (omitted when there are none). Imports by the owner: “Row N: Name updated / Unchanged / Managed through SCIM synchronization; not updated”. Imports by non-owners: row numbers and email addresses skipped because they are already in the organization (optional)
    string
  ]
}
```

**Example Response Values**

```json
{
  "created": 5,
  "added": 2,
  "updated": 1,
  "unchanged": 1,
  "scimSkipped": 1,
  "skippedExisting": 0,
  "importerIsOwner": true,
  "message": [
    "Row 2: Name updated",
    "Row 3: Unchanged",
    "Row 5: Managed through SCIM synchronization; not updated"
  ]
}
```

**Status Code: 400 - Validation error; the entire file is rejected**

**Example Response Schema**

```typescript
{
  "detail"?: // May have different types (optional)
  array[string] // Reason the entire file is rejected. Array of strings: errors listed by row (such as a blank Email or a Name longer than 255 characters), or exceeding the 25,000-row limit per upload; string: a missing required column or a file with no data rows (optional)
  "file"?: [ // The file is not in .xlsx format (optional)
    string
  ]
}
```

**Example Response Values**

```json
{
  "detail": [
    "Row 3: Email cannot be blank",
    "Row 5: Email cannot be blank"
  ]
}
```

***

### List Organizations <a href="#organizations-list" id="organizations-list"></a>

GET `/api/v1/organizations/`

#### Parameters

| Parameter    | Required | Type    | Description                                    |
| ------------ | -------- | ------- | ---------------------------------------------- |
| `page`       | ❌        | integer | A page number within the paginated result set. |
| `pageSize`   | ❌        | integer | Number of results to return per page.          |
| `pagination` | ❌        | string  | Whether to paginate (true/false)               |

#### Code Examples

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

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

# Make sure to replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

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

**Example Response Values**

```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": "Response string",
      "createdAt": "Response string",
      "memberCreatedAt": "Response string",
      "approvalStatus": "Response string"
    }
  ]
}
```

***

### Retrieve Organization Details <a href="#organizations-retrieve" id="organizations-retrieve"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                                  |
| -------------- | -------- | ------ | -------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this organization. |

#### Code Examples

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

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

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status Code: 200**

**Example Response Schema**

```typescript
{
  "id": string (uuid)
  "name": string
  "createdAt": string (timestamp)
  "compactLogo"?: string (uri) // Optional
  "fullLogo"?: string (uri) // Optional
  "themePrimaryColor"?: // May have different types (Optional)
  string // UI theme color for buttons, links, and other elements (HEX format, e.g. #0960bd); leave blank to use the system brand primary color as the frontend fallback (Optional)
  "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. (Optional)
  "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. (Optional)
  "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 // Whether the organization is in a trial period. True when the organization has exactly one trial plan and it is currently active
  "expirationDays": integer // Days since expiration. A positive number indicates days since expiration; null means the plan has not expired or is permanent
  "showTrialBanner": boolean // Controls whether the frontend displays the trial/free plan banner
  "agentScheduleMinIntervalSeconds": integer // Minimum schedule execution interval in seconds, configured by the platform; the frontend displays this minimum when creating or editing a schedule, while the schedule API enforces it
  "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. (Optional)
  "taxId"?: // May have different types (Optional)
  string // Applicant-reported business tax ID (8 digits, optional). Stored as-is; not verified. (Optional)
  "contactPhone"?: string // Applicant-reported contact phone collected at organization creation for approval review. (Optional)
  "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. (Optional)
  "invitationCode"?: string // Optional
  "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.
}
```

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "createdAt": "Response string",
  "compactLogo": "https://example.com/file.jpg",
  "fullLogo": "https://example.com/file.jpg",
  "themePrimaryColor": "Response string",
  "usageStatistics": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "organizationPlan": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "creditWallet": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response 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": "Response string",
  "gatewayTrafficFeePercent": "Response string",
  "platformProcessingFeePercent": "Response string",
  "platformProcessingFeeEnabled": false,
  "isTrial": false,
  "expirationDays": 456,
  "showTrialBanner": false,
  "agentScheduleMinIntervalSeconds": 456,
  "noActivePlanDays": 456,
  "cleanupRemainingDays": 456,
  "estimatedCleanupDate": "Response string",
  "approvalStatus": {},
  "companyName": "Response string",
  "taxId": "Response string",
  "contactPhone": "Response string",
  "applicationMetadata": null,
  "invitationCode": "Response string",
  "ipAllowlistEnabled": false,
  "allowedIpCidrs": "Response string",
  "enforceIpAllowlistOnAdminUi": false,
  "enforceIpAllowlistOnApiKey": false
}
```

***

### Get Current User Details <a href="#users-current-retrieve" id="users-current-retrieve"></a>

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

#### Code Examples

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

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

# Make sure to replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/users/current/", config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```typescript
{
  "id": string (uuid)
  "avatar"?: string (uri) // Optional
  "originalAvatar"?: string (uri) // The original avatar image uploaded by the user (long edge capped at 2048px). Every edit re-crops from this image to avoid cumulative distortion from cropping an already-cropped result. Legacy data from before this feature launched is empty and is not backfilled (Optional)
  "avatarCropBox"?: object // Position and size of the last crop box on the original image (x/y/width/height, with optional rotate/scale_x/scale_y); coordinates are relative to the stored original image (Optional)
  "name": string
  "email": string (email)
  "authSource": 
  {
    "id": string (uuid)
    "name": string
  }
  "company"?: string // Optional
  "invitationCode"?: // Multiple types possible (Optional)
  string // Optional
  "apiKeys": [ // Get the list of the user's API keys in the specified organization.

Flow:
1. Get the current organization instance from the request
2. If there is no organization instance (usually during third-party SSO login), use the user's auth source
   to look up that auth source's default organization (is_auth_source_default_organization=True)

Note:
- During third-party SSO login, the request does not contain organization_instance
- The organization must be located via the auth_source and is_auth_source_default_organization flags
    object
  ]
  "permissions": object // Get the user's permissions in the current organization (nested parent-child structure).
  "resourcePermissions": object // Get the user's resource creation permissions in the current organization.
  "isOwner": boolean // Determine whether the user is an Owner in the current organization.
  "maigptCapabilities": object // The member's effective built-in feature capabilities in MaiGPT (resolved from role permissions), used by the frontend to show/hide features.

When there is no member context (not bound to an organization), the resolved result is fully open, consistent with the resolver's "missing data does not lock out" principle;
hiding in the frontend is only a UX layer, and the authoritative check is the gate in the reply path.
}
```

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "avatar": "https://example.com/file.jpg",
  "originalAvatar": "https://example.com/file.jpg",
  "avatarCropBox": null,
  "name": "Response string",
  "email": "response@example.com",
  "authSource": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Response string"
  },
  "company": "Response string",
  "invitationCode": "Response string",
  "apiKeys": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  ],
  "permissions": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "resourcePermissions": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "isOwner": false,
  "maigptCapabilities": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  }
}
```

***

### Get Current User Permissions <a href="#permissions-list" id="permissions-list"></a>

GET `/api/v1/permissions/`

#### Code Examples

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

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

# Make sure to replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/permissions/", config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

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

**Example Response Values**

```json
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Response string",
    "value": "Response string",
    "description": "Response string",
    "children": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Example response name",
        "description": "Example response description"
      }
    ]
  }
]
```

***

### List Members of a Specified Organization <a href="#organizations-members-list" id="organizations-members-list"></a>

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

#### Parameters

| Parameter          | Required | Type    | Description                                                                                                                                                                                                                                                |
| ------------------ | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `organizationPk`   | ✅        | string  | A UUID string identifying this organization 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  | Whether to paginate (true/false)                                                                                                                                                                                                                           |
| `query`            | ❌        | string  |                                                                                                                                                                                                                                                            |
| `search`           | ❌        | string  |                                                                                                                                                                                                                                                            |
| `withGroupSources` | ❌        | boolean | When true, \`groups\` lists each role only once and additionally returns \`sources\` (how the role was assigned: manual／ldap／scim／eip／cloudflare\_access, deduplicated and sorted; default roles have an empty array). Only supported for paginated lists. |

#### Code Examples

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

```bash
# Example API call (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"

# Before running, replace YOUR_API_KEY and verify the request data.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('An error occurred during the request:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("An error occurred during the request:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'An error occurred during the request: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200**

**Response Schema Example**

```typescript
{
  "count": integer
  "next"?: string (uri) // Optional
  "previous"?: string (uri) // Optional
  "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 // Checks whether the member is an organization owner (via the OWNER Group)

Uses a cache to avoid duplicate queries within the same request
Cache lifetime: valid for as long as the member instance exists

Prefers the annotated result (if available) to avoid duplicate queries
      "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 (optional)
      "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)
    }
  ]
}
```

**Response Example Value**

```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": "Response string",
      "displayName": "Response string",
      "accountName": "Response string",
      "isScimManaged": false,
      "email": "Response string",
      "isActive": false,
      "isOwner": false,
      "permissions": [
        {
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "name": "Response example name",
          "description": "Response example description"
        }
      ],
      "groups": [
        {
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "name": "Response example name",
          "description": "Response example description"
        }
      ],
      "creditQuotaRequired": false,
      "activeQuota": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Response example name",
        "description": "Response example description"
      },
      "metadata": null,
      "availabilityStatus": {},
      "createdAt": "Response string"
    }
  ]
}
```

***

### Get Member Details <a href="#organizations-members-retrieve" id="organizations-members-retrieve"></a>

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

#### Parameters

| Parameter        | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `id`             | ✅        | string | A UUID string identifying this member.         |
| `organizationPk` | ✅        | string | A UUID string identifying this organization ID |

#### Code Examples

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

```bash
# Example API call (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"

# Before running, replace YOUR_API_KEY and verify the request data.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('An error occurred during the request:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("An error occurred during the request:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'An error occurred during the request: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200**

**Response Schema Example**

```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 // Checks whether the member is an organization owner (via the OWNER Group)

Uses a cache to avoid duplicate queries within the same request
Cache lifetime: valid for as long as the member instance exists

Prefers the annotated result (if available) to avoid duplicate queries
  "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 (optional)
  "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)
}
```

**Response Example Value**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "displayName": "Response string",
  "accountName": "Response string",
  "isScimManaged": false,
  "email": "Response string",
  "isActive": false,
  "isOwner": false,
  "permissions": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Response example name",
      "description": "Response example description"
    }
  ],
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Response example name",
      "description": "Response example description"
    }
  ],
  "creditQuotaRequired": false,
  "activeQuota": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Response example name",
    "description": "Response example description"
  },
  "metadata": null,
  "availabilityStatus": {},
  "createdAt": "Response string"
}
```

***

### Update Organization <a href="#organizations-update" id="organizations-update"></a>

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

#### Parameters

| Parameter | Required | Type   | Description                                  |
| --------- | -------- | ------ | -------------------------------------------- |
| `id`      | ✅        | string | A UUID string identifying this organization. |

#### Request Body

**Request Parameters**

| Field                          | Type         | Required | Description                                                                                                                                                                                                 |
| ------------------------------ | ------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name                           | string       | Yes      |                                                                                                                                                                                                             |
| compactLogo                    | string (uri) | No       |                                                                                                                                                                                                             |
| fullLogo                       | string (uri) | No       |                                                                                                                                                                                                             |
| themePrimaryColor              | object       | No       | UI theme color used for buttons, links, and other elements (HEX format, e.g. #0960bd); leave empty for unset, in which case the frontend falls back to the system brand color                               |
| hideChinaModels                | boolean      | No       | 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      | No       | 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       | No       | Applicant-reported company name collected at organization creation for approval review.                                                                                                                     |
| taxId                          | object       | No       | Applicant-reported business tax ID (8 digits, optional). Stored as-is; not verified.                                                                                                                        |
| contactPhone                   | string       | No       | Applicant-reported contact phone collected at organization creation for approval review.                                                                                                                    |
| applicationMetadata            | object       | No       | 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       | No       |                                                                                                                                                                                                             |

**Request Schema Example**

```typescript
{
  "name": string
  "compactLogo"?: string (uri) // Optional
  "fullLogo"?: string (uri) // Optional
  "themePrimaryColor"?: // May be of different types (optional)
  string // UI theme color used for buttons, links, and other elements (HEX format, e.g. #0960bd); leave empty for unset, in which case the frontend falls back to the system brand color (optional)
  "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. (optional)
  "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. (optional)
  "companyName"?: string // Applicant-reported company name collected at organization creation for approval review. (optional)
  "taxId"?: // May be of different types (optional)
  string // Applicant-reported business tax ID (8 digits, optional). Stored as-is; not verified. (optional)
  "contactPhone"?: string // Applicant-reported contact phone collected at organization creation for approval review. (optional)
  "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. (optional)
  "invitationCode"?: string // Optional
}
```

**Request Example Value**

```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": "Free Plan",
    "expired_at": null
  },
  "is_trial": false,
  "expiration_days": null
}
```

#### Code Examples

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

```bash
# Example API call (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": "Free Plan",
      "expired_at": null
    },
    "is_trial": false,
    "expiration_days": null
  }'

# Before running, replace YOUR_API_KEY and verify the request data.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request body (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": "Free Plan",
      "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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('An error occurred during the request:');
    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"
}

# Request body (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": "Free Plan",
        "expired_at": None
    },
    "is_trial": False,
    "expiration_days": None
}

response = requests.put(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("An error occurred during the request:", 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' => 'Free Plan',
                'expired_at' => null
            ],
            'is_trial' => false,
            'expiration_days' => null
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200**

**Example Response Schema**

```typescript
{
  "id": string (uuid) // Organization ID
  "name": string // Organization name
  "created_at": string (timestamp) // Creation timestamp
  "usage_statistics": { // Usage statistics
  {
    "chatbots_count"?: integer // Number of chatbots (optional)
    "countable_chatbots_count"?: integer // Number of chatbots that count toward the creation quota (chatbots with modes outside the plan allowlist are excluded) (optional)
    "exempt_chatbots_by_mode"?: object // Number of chatbots excluded from the quota, grouped by the mode that exempts them (optional)
    "allowed_chatbot_reply_modes"?: [ // Allowlist of reply modes permitted for chatbot creation under the plan (an empty array means no restrictions) (optional)
      string
    ]
    "can_create_chatbot"?: boolean // Whether a chatbot can be created (optional)
    "create_chatbot_limit"?: integer // Maximum number of chatbots that can be created (-1 means unlimited; 0 means creation is prohibited) (optional)
    "current_month_words_count_total"?: integer // Total word limit for the current month (optional)
    "current_month_used_words_count_total"?: integer // Words used this month (optional)
    "current_month_used_conversations_count_total"?: integer // Conversations used this month (optional)
    "available_upload_files_size_total"?: integer // Total size available for file uploads (bytes) (optional)
    "used_upload_file_size_total"?: integer // Size used by uploaded files (bytes) (optional)
  }
  }
  "organization_plan": { // Organization plan information
  {
    "id"?: string (uuid) // Plan ID (optional)
    "plan_name"?: string // Plan name (optional)
    "expired_at"?: string (date-time) // Expiration time (optional)
  }
  }
  "is_trial"?: boolean // Whether the organization is in a trial period. True when the organization has exactly one trial plan and it is currently active (optional)
  "expiration_days"?: integer // Days since expiration. A positive number indicates days since expiration; null indicates a plan that has not expired or a permanent plan (optional)
}
```

**Example Response Values**

```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": "Free Plan",
    "expired_at": null
  },
  "is_trial": false,
  "expiration_days": null
}
```

***

### Update Current User Details <a href="#users-current-update" id="users-current-update"></a>

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

#### Request Body

**Request Parameters**

| Field          | Type           | Required | Description                                                                                                                                                                                                                                                      |
| -------------- | -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| avatar         | string (uri)   | No       |                                                                                                                                                                                                                                                                  |
| originalAvatar | string (uri)   | No       | Original avatar image uploaded by the user (long edge capped at 2048px). Each edit re-crops from this image to avoid cumulative distortion from cropping an already-cropped result. Legacy data from before this feature launched is empty and is not backfilled |
| avatarCropBox  | object         | No       | Position and size of the last crop box on the original image (x/y/width/height, with optional rotate/scale\_x/scale\_y); coordinates are relative to the stored original image                                                                                   |
| name           | string         | Yes      |                                                                                                                                                                                                                                                                  |
| email          | string (email) | Yes      |                                                                                                                                                                                                                                                                  |
| company        | string         | No       |                                                                                                                                                                                                                                                                  |
| invitationCode | object         | No       |                                                                                                                                                                                                                                                                  |

**Request Schema Example**

```typescript
{
  "avatar"?: string (uri) // Optional
  "originalAvatar"?: string (uri) // Original avatar uploaded by the user (long edge limited to 2048px). Every edit re-crops from this image to avoid cumulative distortion from cropping an already-cropped result. Legacy data created before this feature launched is empty and is not backfilled (Optional)
  "avatarCropBox"?: object // Position and size of the last crop box on the original image (x/y/width/height, with optional rotate/scale_x/scale_y); coordinates are relative to the stored original image (Optional)
  "name": string
  "email": string (email)
  "company"?: string // Optional
  "invitationCode"?: // Can be of different types (Optional)
  string // Optional
}
```

**Example Request Values**

```json
{
  "avatar": "https://example.com/file.jpg",
  "originalAvatar": "https://example.com/file.jpg",
  "avatarCropBox": null,
  "name": "Example name",
  "email": "user@example.com",
  "company": "Example string",
  "invitationCode": null
}
```

#### Code Examples

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

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

# Make sure to replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Create FormData object
const formData = new FormData();
// Add form fields

// Set request headers
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('Successfully retrieved response:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Create file and form data
files = {
    'file': ('example.pdf', open('example.pdf', 'rb'), 'application/pdf')
}

response = requests.put(url, files=files, headers=headers)
try:
    print("Successfully retrieved response:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Successfully retrieved response:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

```typescript
{
  "id": string (uuid)
  "avatar"?: string (uri) // Optional
  "originalAvatar"?: string (uri) // Original avatar uploaded by the user (long edge limited to 2048px). Every edit re-crops from this image to avoid cumulative distortion from cropping an already-cropped result. Legacy data created before this feature launched is empty and is not backfilled (Optional)
  "avatarCropBox"?: object // Position and size of the last crop box on the original image (x/y/width/height, with optional rotate/scale_x/scale_y); coordinates are relative to the stored original image (Optional)
  "name": string
  "email": string (email)
  "authSource": 
  {
    "id": string (uuid)
    "name": string
  }
  "company"?: string // Optional
  "invitationCode"?: // Can be of different types (Optional)
  string // Optional
  "apiKeys": [ // Get the list of the user's API keys in the specified organization.

Flow:
1. Get the current organization instance from the request
2. If there is no organization instance (usually during third-party SSO login), use the user's authentication source
   to look up that authentication source's default organization (is_auth_source_default_organization=True)

Note:
- The request does not contain organization_instance during third-party SSO login
- The organization must be located via the auth_source and is_auth_source_default_organization flags
    object
  ]
  "permissions": object // Get the user's permissions in the current organization (nested parent-child structure).
  "resourcePermissions": object // Get the user's resource creation permissions in the current organization.
  "isOwner": boolean // Determine whether the user is an Owner in the current organization.
  "maigptCapabilities": object // Effective built-in feature capabilities of the member in MaiGPT (role permission resolution result), used by the frontend to show/hide features.

When there is no member context (not bound to an organization), the resolved result is all enabled, consistent with the resolver's "do not lock out on missing data"
behavior; hiding in the frontend is only a UX layer, and the authoritative check is the gate on the reply path.
}
```

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "avatar": "https://example.com/file.jpg",
  "originalAvatar": "https://example.com/file.jpg",
  "avatarCropBox": null,
  "name": "Response string",
  "email": "response@example.com",
  "authSource": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Response string"
  },
  "company": "Response string",
  "invitationCode": "Response string",
  "apiKeys": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  ],
  "permissions": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "resourcePermissions": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "isOwner": false,
  "maigptCapabilities": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  }
}
```

***

### Update Member Roles <a href="#organizations-members-update-groups-create" id="organizations-members-update-groups-create"></a>

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

#### Parameters

| Parameter Name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `id`             | ✅        | string | A UUID string identifying this member.         |
| `organizationPk` | ✅        | string | A UUID string identifying this organization ID |

#### Request Body

**Request Parameters**

| Field  | Type           | Required | Description |
| ------ | -------------- | -------- | ----------- |
| groups | array\[string] | Yes      |             |

**Request Schema Example**

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

**Request Example Values**

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

#### Code Examples

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

```bash
# API call example (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"
    ]
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

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

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

```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 // Check whether the member is the organization owner (via the OWNER Group)

Use caching to avoid duplicate queries within the same request
Cache lifetime: valid for the lifetime of the member instance

Prefer annotation results (when available) to avoid duplicate queries
  "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 (Optional)
  "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)
}
```

**Response Example Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "displayName": "Response string",
  "accountName": "Response string",
  "isScimManaged": false,
  "email": "Response string",
  "isActive": false,
  "isOwner": false,
  "permissions": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  ],
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  ],
  "creditQuotaRequired": false,
  "activeQuota": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "metadata": null,
  "availabilityStatus": {},
  "createdAt": "Response string"
}
```

**Status Code: 400**

**Response Schema Example**

```typescript
object
```

***

### Update member name <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" %}
**Required permissions**: Only the organization owner can call this endpoint; non-owners receive `403` even if they have member management permissions. This changes only the member’s display name in this organization (organization-specific name), without changing their account name or affecting other organizations they belong to. Other member data, including roles, quotas, and custom attributes, is unaffected. Leading and trailing whitespace in `displayName` is trimmed. The name can contain up to 255 characters and does not need to be unique. An empty or whitespace-only string clears the name, so the account name (`accountName`) is displayed instead. If the value matches the current display name (`name`, which falls back to the account name when no organization-specific name is set), it is treated as unchanged: nothing is written, no activity is logged, and `200` is still returned. If the member is managed by SCIM (`isScimManaged` is `true`), the endpoint returns `400`; change the name in the identity provider instead. It returns `404` if the member does not belong to this organization. On success, it returns the same member object as “Get specific member details”, with `name` containing the new display name. Actual changes are recorded in the organization’s activity log.
{% endhint %}

#### Parameters

| Parameter name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `id`             | ✅        | string | A UUID string identifying this member.         |
| `organizationPk` | ✅        | string | A UUID string identifying this organization ID |

#### Request body

**Request parameters**

| Field       | Type   | Required | Description                                                                                                                                                          |
| ----------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| displayName | string | Yes      | 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. |

**Request schema example**

```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.
}
```

**Example request values**

```json
{
  "displayName": "Example string"
}
```

#### Code examples

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

```bash
# API call example (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": "Example string"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request body (payload)
const data = {
    "displayName": "Example string"
  };

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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

# Request body (payload)
data = {
    "displayName": "Example string"
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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' => 'Example string'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response body

**Status code: 200**

**Response schema example**

```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 // Check whether the member is the organization owner (via the OWNER Group)

Use caching to avoid duplicate queries within the same request
Cache lifetime: valid for the lifetime of the member instance

Prefer annotation results, if available, to avoid duplicate queries
  "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 (Optional)
  "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)
}
```

**Example response values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "displayName": "Response string",
  "accountName": "Response string",
  "isScimManaged": false,
  "email": "Response string",
  "isActive": false,
  "isOwner": false,
  "permissions": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  ],
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  ],
  "creditQuotaRequired": false,
  "activeQuota": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "metadata": null,
  "availabilityStatus": {},
  "createdAt": "Response string"
}
```

**Status code: 400 - The member is managed by SCIM, the name exceeds 255 characters, or displayName is missing**

**Response schema example**

```typescript
{
  "displayName"?: [ // Error reason: The member is managed by SCIM, the name exceeds 255 characters, or displayName is missing (Optional)
    string
  ]
}
```

**Example response values**

```json
{
  "displayName": [
    "This member’s name is managed by the identity provider (SCIM) and cannot be changed manually"
  ]
}
```

**Status code: 403 - The caller is not the organization owner**

**Response schema example**

```typescript
{
  "detail"?: string // Optional
}
```

**Example response values**

```json
{
  "detail": "Only the organization owner can change the name"
}
```

**Status code: 404 - The member does not exist or does not belong to this organization**

***

### Invite members to the organization <a href="#auth-unified-invitations-create" id="auth-unified-invitations-create"></a>

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

{% hint style="info" %}
The organization associated with the API Key is used. Organization overview permission is required (organization owners are exempt). `emails` accepts up to 100 addresses per request. Registered users become members immediately (returned in `members`); unregistered email addresses receive invitations and join after registration (returned in `mailInvitations`). Existing members are listed in `skippedEmails`. `groups` specifies the roles assigned on joining, in the format `[{"id": "Role ID"}]`. Include `creditQuota` to preset individual quotas for this batch of invitees, allocated only when they join: `quotaLimit` (required), `validUntil` (optional; an ISO 8601 string such as `2026-12-31T23:59:59+08:00`, or a 13-digit millisecond timestamp as a string or number; Taiwan time is used if no time zone is specified; must be in the future; omitting it means no expiration), `resetPeriod` (`none` / `daily` / `weekly` / `monthly`, default `none`), and `note` (optional). Including `creditQuota` also requires Credit management permission, and the organization must use Credit billing. If omitted, the [default quota for new members](https://docs.maiagent.ai/api/api-reference/credit#credit-wallets-new-member-quota-policy-retrieve) applies if enabled.
{% endhint %}

#### Request body

**Request parameters**

| Field                   | Type                                                               | Required | Description                                                           |
| ----------------------- | ------------------------------------------------------------------ | -------- | --------------------------------------------------------------------- |
| creditQuota             | object (with 4 properties: quotaLimit, validUntil, resetPeriod...) | No       | Optional credit quota allocated to the invitee when they join.        |
| creditQuota.quotaLimit  | string (decimal)                                                   | Yes      |                                                                       |
| creditQuota.validUntil  | object                                                             | No       | ISO 8601 date-time or 13-digit epoch milliseconds (string or number). |
| creditQuota.resetPeriod | object                                                             | No       |                                                                       |
| creditQuota.note        | string                                                             | No       |                                                                       |
| groups                  | array\[IdName]                                                     | No       |                                                                       |
| emails                  | array\[string]                                                     | Yes      | Email address list to invite. Up to 100 emails.                       |

**Request schema example**

```typescript
{
  "creditQuota"?:  // Optional credit quota allocated to the invitee when they join. (Optional)
  {
    "quotaLimit": string (decimal)
    "validUntil"?: // May have different types (Optional)
    string (date-time) // ISO 8601 date-time or 13-digit epoch milliseconds (string or number). (Optional)
    "resetPeriod"?:  // Optional
    {
    }
    "note"?: string // Optional
  }
  "groups"?: [ // Optional
    {
      "id": string (uuid)
    }
  ]
  "emails": [ // Email address list to invite. Up to 100 emails.
    string (email)
  ]
}
```

**Example request values**

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

#### Code examples

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

```bash
# API call example (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"
      }
    ]
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

# Request body (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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response body

**Status code: 200**

**Response schema example**

```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) // Optional
      "groups"?: [ // Optional
        {
          "id": string (uuid)
          "name": string
        }
      ]
      "createdAt"?: string (timestamp) // Optional
      "acceptedAt"?: string (timestamp) // Optional
      "lastSentAt": string (timestamp)
      "failureReason": string
      "retryCount": integer
      "canResend": boolean
    }
  ]
  "skippedEmails": [
    string (email)
  ]
}
```

**Example response values**

```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": "New employee quota"
      },
      "creditQuotaSource": "invitation_override"
    }
  ],
  "skippedEmails": []
}
```

**Status code: 400 - Invalid request body, such as an invalid email format, a nonexistent role, an invalid or expired \`creditQuota.validUntil\`, or \`creditQuota\` provided for an organization that does not use Credit billing**

**Status code: 403 - Missing organization overview permission, \`creditQuota\` provided without Credit management permission, or a non-owner assigning the owner role or reinviting a pending invitation with the owner role**

***

### List organization email invitation records <a href="#auth-organization-mail-invitations-list" id="auth-organization-mail-invitations-list"></a>

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

{% hint style="info" %}
Query invitation delivery and acceptance status. Filter with `status`, which accepts multiple values (for example, `status=pending&status=mail_failed`); omit it to return all statuses. Set `pagination=false` to disable pagination. Users with organization overview permission can see invitations across the organization (only organization owners can see invitations assigning the owner role). Other users can see only invitations they sent.
{% endhint %}

#### Parameters

| Parameter name | Required | Type    | Description                                                                                                                      |
| -------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `pagination`   | ❌        | boolean | Whether to paginate                                                                                                              |
| `status`       | ❌        | string  | Invitation status; multiple values are supported (for example, status=pending\&status=mail\_failed). Omit to return all statuses |

#### Code examples

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

```bash
# API call example (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response body

**Status code: 200**

**Response schema example**

```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) // Optional
    "groups"?: [ // Optional
      {
        "id": string (uuid)
        "name": string
      }
    ]
    "createdAt"?: string (timestamp) // Optional
    "acceptedAt"?: string (timestamp) // Optional
    "lastSentAt": string (timestamp)
    "failureReason": string
    "retryCount": integer
    "canResend": boolean
  }
]
```

**Example response values**

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

***

### Resend organization invitation email <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" %}
Requires organization overview permission. No request body is needed. Only pending invitations or invitations with failed delivery can be resent (accepted or revoked invitations return `400`). An invitation can be resent up to 3 times, at intervals of at least 5 minutes.
{% endhint %}

#### Parameters

| Parameter name | Required | Type   | Description |
| -------------- | -------- | ------ | ----------- |
| `id`           | ✅        | string |             |

#### Code examples

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

```bash
# Example API call (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200**

**Example response schema**

```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) // Optional
  "groups"?: [ // Optional
    {
      "id": string (uuid)
      "name": string
    }
  ]
  "createdAt"?: string (timestamp) // Optional
  "acceptedAt"?: string (timestamp) // Optional
  "lastSentAt": string (timestamp)
  "failureReason": string
  "retryCount": integer
  "canResend": boolean
}
```

**Example response values**

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

***

### List Organization API Keys <a href="#organizations-api-keys-list" id="organizations-api-keys-list"></a>

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

{% hint style="info" %}
API key management for administrators requires the API Key Management permission. Members can hold multiple active keys at the same time, allowing you to issue a new key, deploy it, and then revoke the old one. See [API Authentication](https://docs.maiagent.ai/api/preparation/authentication) for how to obtain a key.
{% endhint %}

#### Parameters

| Parameter Name   | Required | Type    | Description                                    |
| ---------------- | -------- | ------- | ---------------------------------------------- |
| `organizationPk` | ✅        | string  | A UUID string identifying this organization 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  |                                                |

#### Code Examples

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

```bash
# API call example (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

```typescript
{
  "count": integer
  "next"?: string (uri) // Optional
  "previous"?: string (uri) // Optional
  "results": [
    {
      "id": string
      "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (Optional)
      "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. (Optional)
      "rateLimitRpm"?: integer // Max requests per minute across every platform API this key can call. Null = unlimited. (Optional)
      "rateLimitTpm"?: integer // Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited. (Optional)
      "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. (Optional)
      "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. (Optional)
      "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. (Optional)
      "createdAt": string (timestamp)
      "lastUsedAt"?: string (timestamp) // Optional
      "member": object
      "createdByName": string
      "revokedAt"?: string (timestamp) // Optional
      "revokedByName": string
    }
  ]
}
```

**Response Example Values**

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

**Status Code: 403 - Insufficient permissions**

***

### Issue an API Key for a Member <a href="#organizations-api-keys-create" id="organizations-api-keys-create"></a>

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

#### Parameters

| Parameter Name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `organizationPk` | ✅        | string | A UUID string identifying this organization ID |

#### Request Body

**Request Parameters**

| Field               | Type               | Required | Description |
| ------------------- | ------------------ | -------- | ----------- |
| name                | string             | Yes      |             |
| expiryDate          | string (timestamp) | No       |             |
| memberId            | string (uuid)      | Yes      |             |
| isActive            | boolean            | No       |             |
| creditBudgetDaily   | string (decimal)   | No       |             |
| creditBudgetMonthly | string (decimal)   | No       |             |

**Request Schema Example**

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

**Request Example Values**

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

#### Code Examples

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

```bash
# API call example (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"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

# Request body (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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 201**

**Response Schema Example**

```typescript
{
  "id": string
  "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (Optional)
  "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. (Optional)
  "expiryDate"?: string (timestamp) // Once API key expires, clients cannot use it anymore. (Optional)
  "createdAt": string (timestamp)
}
```

**Response Example Values**

```json
{
  "id": "Response string",
  "name": "Response string",
  "prefix": "Response string",
  "key": "Response string",
  "status": "Response string",
  "source": "Response string",
  "isActive": false,
  "expiryDate": "Response string",
  "createdAt": "Response string"
}
```

**Status Code: 400 - Validation error (e.g., an empty name or an expiry date in the past)**

**Status Code: 403 - Insufficient permissions**

***

### Retrieve a Specific API Key <a href="#organizations-api-keys-retrieve" id="organizations-api-keys-retrieve"></a>

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

#### Parameters

| Parameter Name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `id`             | ✅        | string |                                                |
| `organizationPk` | ✅        | string | A UUID string identifying this organization ID |

#### Code Examples

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

```bash
# API call example (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

```typescript
{
  "id": string
  "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (Optional)
  "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. (Optional)
  "rateLimitRpm"?: integer // Max requests per minute across every platform API this key can call. Null = unlimited. (Optional)
  "rateLimitTpm"?: integer // Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited. (Optional)
  "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. (Optional)
  "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. (Optional)
  "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. (Optional)
  "createdAt": string (timestamp)
  "lastUsedAt"?: string (timestamp) // Optional
  "member": object
  "createdByName": string
  "revokedAt"?: string (timestamp) // Optional
  "revokedByName": string
  "gatewayAllowedLlmIds": [
    string (uuid)
  ]
}
```

**Example Response Values**

```json
{
  "id": "response string",
  "name": "response string",
  "prefix": "response string",
  "status": "response string",
  "source": "response string",
  "isActive": false,
  "rateLimitRpm": 456,
  "rateLimitTpm": 456,
  "creditBudgetDaily": "response string",
  "creditBudgetMonthly": "response string",
  "creditUsedToday": "response string",
  "creditUsedThisMonth": "response string",
  "gatewayAllowedLlmCount": 456,
  "expiryDate": "response string",
  "createdAt": "response string",
  "lastUsedAt": "response string",
  "member": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "createdByName": "response string",
  "revokedAt": "response string",
  "revokedByName": "response string",
  "gatewayAllowedLlmIds": [
    "550e8400-e29b-41d4-a716-446655440000"
  ]
}
```

***

### Update API Key Settings <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" %}
Adjust the enabled status, requests per minute (RPM), and expiration time. Disabling is reversible; use `DELETE` to revoke the key.
{% endhint %}

#### Parameters

| Parameter Name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `id`             | ✅        | string |                                                |
| `organizationPk` | ✅        | string | A UUID string identifying this organization ID |

#### Request Body

**Request Parameters**

| Field               | Type               | Required | Description                                                                                                                                                                                                   |
| ------------------- | ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name                | string             | No       | A free-form name for the API key. Need not be unique. 50 characters max.                                                                                                                                      |
| isActive            | boolean            | No       | 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            | No       | Max requests per minute across every platform API this key can call. Null = unlimited.                                                                                                                        |
| rateLimitTpm        | integer            | No       | Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited.                                                                                                                       |
| creditBudgetDaily   | string (decimal)   | No       | 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)   | No       | 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) | No       | Once API key expires, clients cannot use it anymore.                                                                                                                                                          |
| lastUsedAt          | string (timestamp) | No       |                                                                                                                                                                                                               |
| revokedAt           | string (timestamp) | No       |                                                                                                                                                                                                               |

**Example Request Schema**

```typescript
{
  "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (Optional)
  "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. (Optional)
  "rateLimitRpm"?: integer // Max requests per minute across every platform API this key can call. Null = unlimited. (Optional)
  "rateLimitTpm"?: integer // Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited. (Optional)
  "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. (Optional)
  "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. (Optional)
  "expiryDate"?: string (timestamp) // Once API key expires, clients cannot use it anymore. (Optional)
  "lastUsedAt"?: string (timestamp) // Optional
  "revokedAt"?: string (timestamp) // Optional
}
```

**Example Request Values**

```json
{
  "name": "Example name",
  "isActive": true,
  "rateLimitRpm": 123,
  "rateLimitTpm": 123,
  "creditBudgetDaily": "example string",
  "creditBudgetMonthly": "example string",
  "expiryDate": "example string",
  "lastUsedAt": "example string",
  "revokedAt": "example string"
}
```

#### Code Examples

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

```bash
# API call example (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": "Example name",
    "isActive": true,
    "rateLimitRpm": 123,
    "rateLimitTpm": 123,
    "creditBudgetDaily": "example string",
    "creditBudgetMonthly": "example string",
    "expiryDate": "example string",
    "lastUsedAt": "example string",
    "revokedAt": "example string"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "name": "Example name",
    "isActive": true,
    "rateLimitRpm": 123,
    "rateLimitTpm": 123,
    "creditBudgetDaily": "example string",
    "creditBudgetMonthly": "example string",
    "expiryDate": "example string",
    "lastUsedAt": "example string",
    "revokedAt": "example string"
  };

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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request Body (payload)
data = {
    "name": "Example name",
    "isActive": True,
    "rateLimitRpm": 123,
    "rateLimitTpm": 123,
    "creditBudgetDaily": "example string",
    "creditBudgetMonthly": "example string",
    "expiryDate": "example string",
    "lastUsedAt": "example string",
    "revokedAt": "example string"
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Example name',
            'isActive' => true,
            'rateLimitRpm' => 123,
            'rateLimitTpm' => 123,
            'creditBudgetDaily' => 'example string',
            'creditBudgetMonthly' => 'example string',
            'expiryDate' => 'example string',
            'lastUsedAt' => 'example string',
            'revokedAt' => 'example string'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```typescript
{
  "id": string
  "name"?: string // A free-form name for the API key. Need not be unique. 50 characters max. (Optional)
  "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. (Optional)
  "rateLimitRpm"?: integer // Max requests per minute across every platform API this key can call. Null = unlimited. (Optional)
  "rateLimitTpm"?: integer // Max LLM tokens per minute through the AI Gateway inference endpoints. Null = unlimited. (Optional)
  "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. (Optional)
  "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. (Optional)
  "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. (Optional)
  "createdAt": string (timestamp)
  "lastUsedAt"?: string (timestamp) // Optional
  "member": object
  "createdByName": string
  "revokedAt"?: string (timestamp) // Optional
  "revokedByName": string
  "gatewayAllowedLlmIds": [
    string (uuid)
  ]
}
```

**Example Response Values**

```json
{
  "id": "response string",
  "name": "response string",
  "prefix": "response string",
  "status": "response string",
  "source": "response string",
  "isActive": false,
  "rateLimitRpm": 456,
  "rateLimitTpm": 456,
  "creditBudgetDaily": "response string",
  "creditBudgetMonthly": "response string",
  "creditUsedToday": "response string",
  "creditUsedThisMonth": "response string",
  "gatewayAllowedLlmCount": 456,
  "expiryDate": "response string",
  "createdAt": "response string",
  "lastUsedAt": "response string",
  "member": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "createdByName": "response string",
  "revokedAt": "response string",
  "revokedByName": "response string",
  "gatewayAllowedLlmIds": [
    "550e8400-e29b-41d4-a716-446655440000"
  ]
}
```

***

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

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

#### Parameters

| Parameter Name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `id`             | ✅        | string |                                                |
| `organizationPk` | ✅        | string | A UUID string identifying this Organization ID |

#### Code Examples

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

```bash
# Example API Call (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request Body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Content

| Status Code | Description                      |
| ----------- | -------------------------------- |
| 204         | API Key revoked successfully     |
| 400         | API Key has already been revoked |
| 403         | Insufficient permissions         |
| 404         | API Key not found                |

***

### Get the Organization an API Key Belongs To <a href="#users-api-key-context-retrieve" id="users-api-key-context-retrieve"></a>

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

{% hint style="info" %}
Accepts only `Authorization: Api-Key` and returns the organization the key is bound to; it does not count toward the key's RPM quota. For usage, see [Common Conventions: Confirm the Organization a Key Belongs To](https://docs.maiagent.ai/api/preparation/conventions#api-key-context)。
{% endhint %}

#### Code Examples

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

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

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Content

**Status Code: 200**

**Example Response Structure**

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

**Example Response Values**

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

**Status Code: 401 - Missing or invalid API Key, or a non-API-Key credential was used**

***

### Issue a Member Embed Token <a href="#members-embed-tokens-create" id="members-embed-tokens-create"></a>

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

{% hint style="info" %}
Uses an organization API Key to issue a token valid for 15 minutes for a specified member, so your system can embed MaiGPT as that member. Only keys held by the organization owner or by members with the "Organization Overview" management permission can call this endpoint. For the flow, see the technical manual [MaiGPT Member Identity Embedding](https://docs.maiagent.ai/tech/work/maigpt-integration)。
{% endhint %}

#### Request Body

**Request Parameters**

| Field    | Type           | Required | Description |
| -------- | -------------- | -------- | ----------- |
| email    | string (email) | No       |             |
| memberId | string (uuid)  | No       |             |

**Request Schema Example**

```typescript
{
  "email"?: string (email) // Optional
  "memberId"?: string (uuid) // Optional
}
```

**Example Request Values**

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

#### Code Examples

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

```bash
# Example API Call (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"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

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

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 201**

**Response Schema Example**

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

**Example Response Values**

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

**Status Code: 400 - Provide exactly one of email and memberId**

**Status Code: 401 - Not authenticated with an Api-Key**

**Status Code: 403 - The API Key holder is neither an organization owner nor has organization management permission**

**Status Code: 404 - The specified member does not exist, is disabled, or does not belong to this organization**

***

### List OAuth Applications <a href="#oauth-applications-list" id="oauth-applications-list"></a>

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

{% hint style="info" %}
When MaiAgent acts as an OAuth 2.1 authorization server, your application registers here first. For the flow, see the technical manual [MaiAgent as an OAuth Authorization Server](https://docs.maiagent.ai/tech/authorization-integration/maiagent-oauth-server).
{% endhint %}

#### Parameters

| Parameter Name | Required | Type    | Description                                    |
| -------------- | -------- | ------- | ---------------------------------------------- |
| `page`         | ❌        | integer | A page number within the paginated result set. |
| `pageSize`     | ❌        | integer | Number of results to return per page.          |

#### Code Examples

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

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

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

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

**Example Response Values**

```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": "Response string",
      "clientId": "Response string",
      "clientType": {},
      "redirectUris": [
        "Response string"
      ],
      "authorizedUserCount": 456,
      "createdByName": "Response string",
      "created": "Response string",
      "updated": "Response string"
    }
  ]
}
```

***

### Register OAuth Application <a href="#oauth-applications-create" id="oauth-applications-create"></a>

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

#### Request Body

**Request Parameters**

| Field        | Type           | Required | Description |
| ------------ | -------------- | -------- | ----------- |
| name         | string         | Yes      |             |
| clientType   | object         | No       |             |
| redirectUris | array\[string] | Yes      |             |

**Request Schema Example**

```typescript
{
  "name": string
  "clientType"?:  // Optional
  {
  }
  "redirectUris": [
    string
  ]
}
```

**Example Request Values**

```json
{
  "name": "Example name",
  "clientType": {},
  "redirectUris": [
    "Example string"
  ]
}
```

#### Code Examples

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

```bash
# Example API Call (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": "Example name",
    "clientType": {},
    "redirectUris": [
      "Example string"
    ]
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "name": "Example name",
    "clientType": {},
    "redirectUris": [
      "Example string"
    ]
  };

axios.post("https://api.maiagent.ai/api/v1/oauth/applications/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request Body (payload)
data = {
    "name": "Example name",
    "clientType": {},
    "redirectUris": [
        "Example string"
    ]
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Example name',
            'clientType' => new \stdClass(),
            'redirectUris' => [
                'Example string'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 201**

**Response Schema Example**

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

**Example Response Values**

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

***

### Retrieve OAuth Application <a href="#oauth-applications-retrieve" id="oauth-applications-retrieve"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                                                |
| -------------- | -------- | ------ | ---------------------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this MaiAgent OAuth application. |

#### Code Examples

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

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

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

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

**Example Response Values**

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

***

### Update OAuth Application <a href="#oauth-applications-partial-update" id="oauth-applications-partial-update"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                                                |
| -------------- | -------- | ------ | ---------------------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this MaiAgent OAuth application. |

#### Request Body

**Request Parameters**

| Field        | Type           | Required | Description |
| ------------ | -------------- | -------- | ----------- |
| name         | string         | No       |             |
| redirectUris | array\[string] | No       |             |

**Request Schema Example**

```typescript
{
  "name"?: string // Optional
  "redirectUris"?: [ // Optional
    string
  ]
}
```

**Example Request Values**

```json
{
  "name": "Example name",
  "redirectUris": [
    "Example string"
  ]
}
```

#### Code Examples

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

```bash
# Example API Call (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": "Example name",
    "redirectUris": [
      "Example string"
    ]
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "name": "Example name",
    "redirectUris": [
      "Example string"
    ]
  };

axios.patch("https://api.maiagent.ai/api/v1/oauth/applications/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request Body (payload)
data = {
    "name": "Example name",
    "redirectUris": [
        "Example string"
    ]
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Example name',
            'redirectUris' => [
                'Example string'
            ]
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

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

**Example Response Values**

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

***

### Delete OAuth Application and Revoke Its Tokens <a href="#oauth-applications-destroy" id="oauth-applications-destroy"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                                                |
| -------------- | -------- | ------ | ---------------------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this MaiAgent OAuth application. |

#### Code Examples

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

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

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request Body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

| Status Code | Description      |
| ----------- | ---------------- |
| 204         | No response body |

***

### Regenerate Client Secret <a href="#oauth-applications-regenerate-secret-create" id="oauth-applications-regenerate-secret-create"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                                                |
| -------------- | -------- | ------ | ---------------------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this MaiAgent OAuth application. |

#### Code Examples

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

```bash
# Example API Call (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"

# Please make sure to replace YOUR_API_KEY and verify the request data before executing.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request Body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

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

**Response Example**

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

***

### List OAuth applications I have authorized <a href="#oauth-authorized-applications-list" id="oauth-authorized-applications-list"></a>

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

#### Parameters

| Parameter Name | Required | Type    | Description                                    |
| -------------- | -------- | ------- | ---------------------------------------------- |
| `page`         | ❌        | integer | A page number within the paginated result set. |
| `pageSize`     | ❌        | integer | Number of results to return per page.          |

#### Code Examples

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

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

# Please make sure to replace YOUR_API_KEY and verify the request data before executing.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

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

**Response Example**

```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": "Response string",
      "organization": "550e8400-e29b-41d4-a716-446655440000",
      "organizationName": "Response string",
      "tokenCount": 456,
      "lastAuthorizedAt": "Response string",
      "latestExpiresAt": "Response string"
    }
  ]
}
```

***

### Revoke my authorization for an application <a href="#oauth-authorized-applications-destroy" id="oauth-authorized-applications-destroy"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description |
| -------------- | -------- | ------ | ----------- |
| `id`           | ✅        | string |             |

#### Code Examples

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

```bash
# Example API Call (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"

# Please make sure to replace YOUR_API_KEY and verify the request data before executing.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request Body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

| Status Code | Description      |
| ----------- | ---------------- |
| 204         | No response body |

***

### Delete organization <a href="#organizations-destroy" id="organizations-destroy"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                                  |
| -------------- | -------- | ------ | -------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Organization. |

#### Code Examples

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

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

# Please make sure to replace YOUR_API_KEY and verify the request data before executing.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request Body (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/organizations/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

| Status Code | Description      |
| ----------- | ---------------- |
| 204         | No response body |

***

### Delete a specified member <a href="#organizations-members-destroy" id="organizations-members-destroy"></a>

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

#### Parameters

| Parameter Name   | Required | Type   | Description                                    |
| ---------------- | -------- | ------ | ---------------------------------------------- |
| `id`             | ✅        | string | A UUID string identifying this Member.         |
| `organizationPk` | ✅        | string | A UUID string identifying this Organization ID |

#### Code Examples

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

```bash
# Example API Call (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"

# Please make sure to replace YOUR_API_KEY and verify the request data before executing.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request Body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

| Status Code | Description      |
| ----------- | ---------------- |
| 204         | No response body |

***

### Get member usage statistics <a href="#organizations-usage-statistics-members-list" id="organizations-usage-statistics-members-list"></a>

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

#### Parameters

| Parameter Name    | Required | Type    | Description                                                                                                                                                                                                              |
| ----------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `organizationPk`  | ✅        | string  | A UUID string identifying this Organization ID                                                                                                                                                                           |
| `chatbot`         | ❌        | string  | Filter by a specific AI assistant ID                                                                                                                                                                                     |
| `chatbotId`       | ❌        | string  |                                                                                                                                                                                                                          |
| `endDate`         | ❌        | string  | End date, format: YYYY-MM-DD                                                                                                                                                                                             |
| `includeTime`     | ❌        | boolean | Whether to return time-series data aggregated by time only, for trend charts (true/false). When set to true, the response contains no entity information, only time fields and statistical values, and is not paginated. |
| `memberId`        | ❌        | string  |                                                                                                                                                                                                                          |
| `page`            | ❌        | integer | Page number                                                                                                                                                                                                              |
| `pageSize`        | ❌        | integer | Number of items per page                                                                                                                                                                                                 |
| `search`          | ❌        | string  | Search by member ID, name, or Email                                                                                                                                                                                      |
| `sortBy`          | ❌        | string  | Sort field                                                                                                                                                                                                               |
| `sortOrder`       | ❌        | string  | Sort order (asc/desc)                                                                                                                                                                                                    |
| `startDate`       | ✅        | string  | Start date, format: YYYY-MM-DD                                                                                                                                                                                           |
| `timeGranularity` | ❌        | string  | Time granularity (hour/day/month)                                                                                                                                                                                        |

#### Code Examples

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

```bash
# Example API Call (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"

# Please make sure to replace YOUR_API_KEY and verify the request data before executing.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

```typescript
{
  "count": integer
  "next"?: string (uri) // optional
  "previous"?: string (uri) // optional
  "results": [
    {
      "count"?: integer // Result count (optional)
      "results"?: [ // optional
        {
          "member"?: { // optional
          {
            "id"?: string (uuid) // Member ID (optional)
            "name"?: string // Member name (optional)
            "email"?: string // Member email (optional)
          }
          }
          "datetime"?: string (date-time) // Timestamp (only appears when include_time=true and time_granularity=hour) (optional)
          "period"?: string (date) // Date (only appears when include_time=true and time_granularity=day/month) (optional)
          "input_characters_count"?: integer // Input character count (optional)
          "output_characters_count"?: integer // Output character count (optional)
          "input_token_usage"?: integer // Input token count (optional)
          "output_token_usage"?: integer // Output token count (optional)
          "messages_count"?: integer // Message count (optional)
          "conversations_count"?: integer // Conversation count (optional)
          "total_characters_count"?: integer // Total character count (optional)
          "total_token_usage"?: integer // Total token count (optional)
        }
      ]
    }
  ]
}
```

**Response Example**

```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": "Wang Xiaoming",
            "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
        }
      ]
    }
  ]
}
```

***

### Retrieve Member Usage Statistics Summary <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/`

#### Parameters

| Parameter Name    | Required | Type   | Description                                    |
| ----------------- | -------- | ------ | ---------------------------------------------- |
| `organizationPk`  | ✅        | string | A UUID string identifying this organization ID |
| `endDate`         | ❌        | string | End date, format: YYYY-MM-DD                   |
| `startDate`       | ✅        | string | Start date, format: YYYY-MM-DD                 |
| `timeGranularity` | ❌        | string | Time granularity (hour/day/month)              |

#### Code Examples

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

```bash
# API call example (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response retrieved successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response retrieved successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response retrieved successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Content

**Status Code: 200**

**Example Response Schema**

```typescript
{
  "totalInputCharacters"?: integer // Total input characters (Optional)
  "totalOutputCharacters"?: integer // Total output characters (Optional)
  "totalCharacters"?: integer // Total characters (Optional)
  "totalInputTokens"?: integer // Total input tokens (Optional)
  "totalOutputTokens"?: integer // Total output tokens (Optional)
  "totalTokens"?: integer // Total tokens (Optional)
  "totalMessages"?: integer // Total messages (Optional)
  "totalConversations"?: integer // Total conversations (Optional)
  "chatbotScope"?: string (enum: organization, accessible_chatbots) // Usage statistics scope for the caller: organization = the entire organization; accessible_chatbots = only AI assistants authorized for the caller's roles (Optional)
  "totalCount"?: integer // Number of hourly member statistics records matching the query: each combination of member, hour, and AI assistant counts as a separate record; this is not the number of members (Optional)
}
```

**Example Response Values**

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

***

### Get AI Assistant Usage Statistics <a href="#organizations-usage-statistics-chatbots-list" id="organizations-usage-statistics-chatbots-list"></a>

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

#### Parameters

| Parameter Name    | Required | Type    | Description                                                                                                                                                                                                      |
| ----------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `organizationPk`  | ✅        | string  | A UUID string identifying this Organization ID                                                                                                                                                                   |
| `chatbotId`       | ❌        | string  |                                                                                                                                                                                                                  |
| `endDate`         | ❌        | string  | End date, format: YYYY-MM-DD                                                                                                                                                                                     |
| `includeTime`     | ❌        | boolean | Whether to return time-series data aggregated by time only, for trend charts (true/false). When set to true, the response contains no entity information, only time fields and statistics, and is not paginated. |
| `page`            | ❌        | integer | Page number                                                                                                                                                                                                      |
| `pageSize`        | ❌        | integer | Number of results per page                                                                                                                                                                                       |
| `search`          | ❌        | string  | Search by AI assistant ID or name                                                                                                                                                                                |
| `sortBy`          | ❌        | string  | Sort field                                                                                                                                                                                                       |
| `sortOrder`       | ❌        | string  | Sort order (asc/desc)                                                                                                                                                                                            |
| `startDate`       | ✅        | string  | Start date, format: YYYY-MM-DD                                                                                                                                                                                   |
| `timeGranularity` | ❌        | string  | Time granularity (hour/day/month)                                                                                                                                                                                |

#### Code Examples

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

```bash
# Example API call (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('An error occurred during the request:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("An error occurred during the request:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'An error occurred during the request: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Response Schema Example**

```typescript
{
  "count": integer
  "next"?: string (uri) // Optional
  "previous"?: string (uri) // Optional
  "results": [
    {
      "count"?: integer // Number of results (Optional)
      "results"?: [ // Optional
        {
          "chatbot"?: { // Optional
          {
            "id"?: string (uuid) // AI assistant ID (Optional)
            "name"?: string // AI assistant name (Optional)
          }
          }
          "datetime"?: string (date-time) // Timestamp (appears only when include_time=true and time_granularity=hour) (Optional)
          "period"?: string (date) // Date (appears only when include_time=true and time_granularity=day/month) (Optional)
          "input_characters_count"?: integer // Input characters (Optional)
          "output_characters_count"?: integer // Output characters (Optional)
          "input_token_usage"?: integer // Input tokens (Optional)
          "output_token_usage"?: integer // Output tokens (Optional)
          "messages_count"?: integer // Messages (Optional)
          "conversations_count"?: integer // Conversations (Optional)
          "total_characters_count"?: integer // Total characters (Optional)
          "total_token_usage"?: integer // Total tokens (Optional)
        }
      ]
    }
  ]
}
```

**Example Response Values**

```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": "Customer Service Assistant"
          },
          "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
        }
      ]
    }
  ]
}
```

***

### Retrieve AI Assistant Usage Statistics Summary <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/`

#### Parameters

| Parameter Name    | Required | Type   | Description                                    |
| ----------------- | -------- | ------ | ---------------------------------------------- |
| `organizationPk`  | ✅        | string | A UUID string identifying this organization ID |
| `endDate`         | ❌        | string | End date, format: YYYY-MM-DD                   |
| `startDate`       | ✅        | string | Start date, format: YYYY-MM-DD                 |
| `timeGranularity` | ❌        | string | Time granularity (hour/day/month)              |

#### Code Examples

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

```bash
# API call example (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response retrieved successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response retrieved successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response retrieved successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200**

**Example Response Schema**

```typescript
{
  "totalInputCharacters"?: integer // Total input characters (Optional)
  "totalOutputCharacters"?: integer // Total output characters (Optional)
  "totalCharacters"?: integer // Total characters (Optional)
  "totalInputTokens"?: integer // Total input tokens (Optional)
  "totalOutputTokens"?: integer // Total output tokens (Optional)
  "totalTokens"?: integer // Total tokens (Optional)
  "totalMessages"?: integer // Total messages (Optional)
  "totalConversations"?: integer // Total conversations (Optional)
  "chatbotScope"?: string (enum: organization, accessible_chatbots) // Usage statistics scope for the caller: organization = the entire organization; accessible_chatbots = only AI assistants authorized for the caller’s roles (Optional)
  "totalChatbots"?: integer // Number of unique AI assistants with usage records during the query period; excludes assistants with no usage during that period and is not the total number of AI assistants in the organization (Optional)
}
```

**Example Response Values**

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

***

### List Your Memories <a href="#me-memories-list" id="me-memories-list"></a>

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

{% hint style="info" %}
Include the `X-Organization-Id` header to specify the organization to operate on, including when calling with an API key. Use the `status` (`active`/`expired`) and `kind` (`fact`/`preference`/`instruction`) query parameters to filter results; pending and rejected memories are excluded. For behavior details, see [Member Memory Management API](https://docs.maiagent.ai/tech/api-integration/endpoint-behaviors/member-memory-api) in the technical manual.
{% endhint %}

#### Parameters

| Parameter Name | Required | Type    | Description                                                                                                               |
| -------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| `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;                                |

#### Code Examples

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

```bash
# API call example (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```typescript
{
  "count": integer
  "next"?: string (uri) // Optional
  "previous"?: string (uri) // Optional
  "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": // May have different types
      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)
    }
  ]
}
```

**Example Response Values**

```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": "Response string",
      "category": "personal_info",
      "categoryDisplay": "Response string",
      "summary": "Response string",
      "details": null,
      "kind": {},
      "source": {},
      "requestedByUser": false,
      "status": {},
      "createdAt": "Response string",
      "updatedAt": "Response string"
    }
  ]
}
```

***

### Create or Update Your Memories <a href="#me-memories-create" id="me-memories-create"></a>

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

{% hint style="info" %}
Include the `X-Organization-Id` header to specify the organization to operate on, including when calling with an API key. Request fields: `topic` (required, up to 100 characters; only lowercase English letters, digits, and underscores between them), `summary` (required, up to 500 characters), `details` (required, an array of strings with up to 20 items, each up to 500 characters), and `kind` (`fact`/`preference`/`instruction`, default: `fact`). If the same member already has an active memory with the same `topic`, update it and return 200; return 201 when creating a new memory.
{% endhint %}

#### Request Body

**Request Parameters**

| Field    | Type                                                                                                                                                    | Required | Description                                                                                                                                                                                                 |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| topic    | string                                                                                                                                                  | Yes      |                                                                                                                                                                                                             |
| category | string (enum: personal\_info, work\_role, projects, communication, response\_format, tools\_tech, interests, health\_lifestyle, schedule\_plans, other) | No       | `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                                                                                                                                                  | Yes      |                                                                                                                                                                                                             |
| details  | array\[string]                                                                                                                                          | Yes      |                                                                                                                                                                                                             |
| kind     | object                                                                                                                                                  | No       |                                                                                                                                                                                                             |

**Example Request Schema**

```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 (Optional)
  "summary": string
  "details": [
    string
  ]
  "kind"?:  // Optional
  {
  }
}
```

**Example Request Values**

```json
{
  "topic": "Example string",
  "category": "personal_info",
  "summary": "Example string",
  "details": [
    "Example string"
  ],
  "kind": {}
}
```

#### Code Examples

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

```bash
# API call example (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": "Example string",
    "category": "personal_info",
    "summary": "Example string",
    "details": [
      "Example string"
    ],
    "kind": {}
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "topic": "Example string",
    "category": "personal_info",
    "summary": "Example string",
    "details": [
      "Example string"
    ],
    "kind": {}
  };

axios.post("https://api.maiagent.ai/api/v1/me/memories/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request Body (payload)
data = {
    "topic": "Example string",
    "category": "personal_info",
    "summary": "Example string",
    "details": [
        "Example string"
    ],
    "kind": {}
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Example string',
            'category' => 'personal_info',
            'summary' => 'Example string',
            'details' => [
                'Example string'
            ],
            'kind' => new \stdClass()
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```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": // May have different types
  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)
}
```

**Example Response Values**

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

**Status Code: 201**

**Example Response Schema**

```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": // May have different types
  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)
}
```

**Example Response Values**

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

***

### Modify or Reactivate Your Memories <a href="#me-memories-partial-update" id="me-memories-partial-update"></a>

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

{% hint style="info" %}
Include the `X-Organization-Id` header to specify the organization to operate on, including when calling with an API key. Provide `topic`, `summary`, or `details` (with the same limits as for creation) to modify the content, or `status` (`active`/`expired`) to deactivate or reactivate the memory; provide at least one of these fields.
{% endhint %}

#### Parameters

| Parameter Name | Required | Type   | Description                                  |
| -------------- | -------- | ------ | -------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Memory Entry. |

#### Request Body

**Request Parameters**

| Field    | Type                                                                                                                                                    | Required | Description                                                                                                                                                                                                 |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| topic    | string                                                                                                                                                  | No       |                                                                                                                                                                                                             |
| category | string (enum: personal\_info, work\_role, projects, communication, response\_format, tools\_tech, interests, health\_lifestyle, schedule\_plans, other) | No       | `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                                                                                                                                                  | No       |                                                                                                                                                                                                             |
| details  | array\[string]                                                                                                                                          | No       |                                                                                                                                                                                                             |
| status   | string (enum: active, expired)                                                                                                                          | No       | `active`: active ; `expired`: expired;                                                                                                                                                                      |

**Example Request Schema**

```typescript
{
  "topic"?: string // Optional
  "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 (Optional)
  "summary"?: string // Optional
  "details"?: [ // Optional
    string
  ]
  "status"?: string (enum: active, expired) // * `active` - active
* `expired` - expired (Optional)
}
```

**Example Request Values**

```json
{
  "topic": "Example string",
  "category": "personal_info",
  "summary": "Example string",
  "details": [
    "Example string"
  ],
  "status": "active"
}
```

#### Code Examples

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

```bash
# API call example (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": "Example string",
    "category": "personal_info",
    "summary": "Example string",
    "details": [
      "Example string"
    ],
    "status": "active"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Configure request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request body (payload)
const data = {
    "topic": "Example string",
    "category": "personal_info",
    "summary": "Example string",
    "details": [
      "Example string"
    ],
    "status": "active"
  };

axios.patch("https://api.maiagent.ai/api/v1/me/memories/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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"
}

# Request body (payload)
data = {
    "topic": "Example string",
    "category": "personal_info",
    "summary": "Example string",
    "details": [
        "Example string"
    ],
    "status": "active"
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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' => 'Example string',
            'category' => 'personal_info',
            'summary' => 'Example string',
            'details' => [
                'Example string'
            ],
            'status' => 'active'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```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": // May have different types
  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)
}
```

**Example Response Values**

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

***

### Delete Your Own Memory <a href="#me-memories-destroy" id="me-memories-destroy"></a>

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

{% hint style="info" %}
Include the `X-Organization-Id` header to specify the organization to operate on, including when calling with an API key.
{% endhint %}

#### Parameters

| Parameter Name | Required | Type   | Description                                  |
| -------------- | -------- | ------ | -------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Memory Entry. |

#### Code Examples

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

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

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Configure request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

| Status Code | Description      |
| ----------- | ---------------- |
| 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/en/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.
