> For the complete documentation index, see [llms.txt](https://docs.clickai.vn/clickai-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clickai.vn/clickai-docs/clickai-docs-en/developer/integrate-clickai-via-restful-api.md).

# Integrate ClickAI via RESTful API

## Table of Contents

·       \[How API Integration Works]\(#how-api-integration-works)

·       \[Getting Started]\(#getting-started)

·       \[Authentication]\(#authentication)

·       \[List Assistants API]\(#list-assistants-api)

·       \[Text Generation App API]\(#text-generation-app-api)

·       \[Conversational App API]\(#conversational-app-api)

·       \[Workflow App API]\(#workflow-app-api)

·       \[Managing conversation\_id]\(#managing-conversation\_id)

·       \[Streaming vs Blocking Response]\(#streaming-vs-blocking-response)

·       \[File Upload API]\(#file-upload-api)

·       \[Feedback API]\(#feedback-api)

·       \[Conversations API]\(#conversations-api)

·       \[Error Handling]\(#error-handling)

·       \[Rate Limits]\(#rate-limits)

·       \[SDK & Libraries]\(#sdk--libraries)

&#x20;

## How API Integration Works

1\.     Build your AI app in ClickAI Studio

2\.     Generate API credentials (Secret Key)

3\.     Call the API from your application

4\.     Users interact through your custom interface — ClickAI handles AI processing behind the scenes

&#x20;

## Getting Started

### Step 1: Access API Settings

5\.     Open your app in ClickAI Studio

6\.     Click "Publish" → Select "API" tab

7\.     View auto-generated API documentation for your app

### Step 2: Create API Key

8\.     In the API tab, click "+ Create API Key"

9\.     Set a descriptive name (e.g., production-backend)

10\.  Copy Secret Key — store securely, shown only once

### Step 3: Identify the right endpoint

ClickAI has two base URLs depending on the API type:

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Base URL</td><td valign="top">Used for</td></tr><tr><td valign="top">https://clickai.io</td><td valign="top">Studio / Console APIs (manage apps, workspace)</td></tr><tr><td valign="top">https://api.clickai.io</td><td valign="top">App Runtime APIs (chat, workflow, files)</td></tr></tbody></table>

&#x20;

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">App Type</td><td valign="top">Base</td><td valign="top">Endpoint</td></tr><tr><td valign="top">List Assistants</td><td valign="top">clickai.io</td><td valign="top">GET /assistant/api/assistant/my-assistants</td></tr><tr><td valign="top">Text Generation</td><td valign="top">api.clickai.io</td><td valign="top">POST /v1/completion-messages</td></tr><tr><td valign="top">Chatbot / Agent</td><td valign="top">api.clickai.io</td><td valign="top">POST /v1/chat-messages</td></tr><tr><td valign="top">Workflow</td><td valign="top">api.clickai.io</td><td valign="top">POST /v1/workflows/run</td></tr></tbody></table>

&#x20;

&#x20;

## Authentication

All API requests require a Bearer Token in the header:

Authorization: Bearer {YOUR\_SECRET\_KEY}\
Content-Type: application/json

🛑 CAUTION: \*\*API Key Security:\*\* NEVER place API Keys in client-side code. NEVER commit API Keys to Git. Always call API from backend servers. Store keys in environment variables.

&#x20;

## List Assistants API

Retrieve the list of assistants (apps) in your workspace.

### Endpoint

GET <https://clickai.io/assistant/api/assistant/my-assistants>

### Query Parameters

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Parameter</td><td valign="top">Type</td><td valign="top">Required</td><td valign="top">Description</td></tr><tr><td valign="top">page</td><td valign="top">integer</td><td valign="top">❌</td><td valign="top">Current page (default: 1)</td></tr><tr><td valign="top">page_size</td><td valign="top">integer</td><td valign="top">❌</td><td valign="top">Items per page (default: 10)</td></tr><tr><td valign="top">mode</td><td valign="top">string</td><td valign="top">❌</td><td valign="top">App type: workflow, agent-chat, chat, completion</td></tr><tr><td valign="top">workspace_id</td><td valign="top">string</td><td valign="top">✅</td><td valign="top">Your workspace ID</td></tr></tbody></table>

&#x20;

### Example — List Workflow Apps

curl -G '<https://clickai.io/assistant/api/assistant/my-assistants>' \\\
&#x20; -d 'page=1' \\\
&#x20; -d 'page\_size=10' \\\
&#x20; -d 'mode=workflow' \\\
&#x20; -d 'workspace\_id=\<YOUR\_WORKSPACE\_ID>' \\\
&#x20; -H 'accept: application/json' \\\
&#x20; -H 'authorization: Bearer \<YOUR\_ACCESS\_TOKEN>'

### Example — List Agent Chat Apps

curl -G '<https://clickai.io/assistant/api/assistant/my-assistants>' \\\
&#x20; -d 'page=1' \\\
&#x20; -d 'page\_size=10' \\\
&#x20; -d 'mode=agent-chat' \\\
&#x20; -d 'workspace\_id=\<YOUR\_WORKSPACE\_ID>' \\\
&#x20; -H 'accept: application/json' \\\
&#x20; -H 'authorization: Bearer \<YOUR\_ACCESS\_TOKEN>'

### Example — Python

import requests\
\
url = "<https://clickai.io/assistant/api/assistant/my-assistants"\\>
headers = {\
&#x20;   'accept': 'application/json',\
&#x20;   'authorization': 'Bearer YOUR\_ACCESS\_TOKEN',\
}\
params = {\
&#x20;   'page': 1,\
&#x20;   'page\_size': 10,\
&#x20;   'mode': 'workflow',\
&#x20;   'workspace\_id': 'YOUR\_WORKSPACE\_ID'\
}\
\
response = requests.get(url, headers=headers, params=params)\
data = response.json()\
for app in data.get('data', \[]):\
&#x20;   print(f"App: {app\['name']} (ID: {app\['id']})")

💡 TIP: Use this API to automatically list apps in your workspace, useful for MCP integration or managing apps via scripts.

&#x20;

## Text Generation App API

For single-turn content generation apps without conversation history.

### Endpoint

POST <https://api.clickai.io/v1/completion-messages>

### Request Body

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Field</td><td valign="top">Type</td><td valign="top">Required</td><td valign="top">Description</td></tr><tr><td valign="top">inputs</td><td valign="top">object</td><td valign="top">✅</td><td valign="top">Input variables as configured in app</td></tr><tr><td valign="top">response_mode</td><td valign="top">string</td><td valign="top">✅</td><td valign="top">"streaming" or "blocking"</td></tr><tr><td valign="top">user</td><td valign="top">string</td><td valign="top">✅</td><td valign="top">Unique user ID for tracking</td></tr><tr><td valign="top">files</td><td valign="top">array</td><td valign="top">❌</td><td valign="top">Attached files (if app supports)</td></tr></tbody></table>

&#x20;

### Example — cURL

curl --location --request POST '<https://api.clickai.io/v1/completion-messages>' \\\
&#x20; \--header 'Authorization: Bearer YOUR-SECRET-KEY' \\\
&#x20; \--header 'Content-Type: application/json' \\\
&#x20; \--data-raw '{\
&#x20;   "inputs": {\
&#x20;     "text": "Write a thank-you email to a customer"\
&#x20;   },\
&#x20;   "response\_mode": "streaming",\
&#x20;   "user": "user-abc-123"\
&#x20; }'

### Example — Python

import requests\
import json\
\
url = "<https://api.clickai.io/v1/completion-messages"\\>
headers = {\
&#x20;   'Authorization': 'Bearer YOUR-SECRET-KEY',\
&#x20;   'Content-Type': 'application/json',\
}\
data = {\
&#x20;   "inputs": {"text": "Write a thank-you email"},\
&#x20;   "response\_mode": "streaming",\
&#x20;   "user": "user-abc-123"\
}\
response = requests.post(url, headers=headers, data=json.dumps(data))\
print(response.text)

### Example — JavaScript (Node.js)

const axios = require('axios');\
\
const response = await axios.post(\
&#x20; '<https://api.clickai.io/v1/completion-messages',\\>
&#x20; {\
&#x20;   inputs: { text: 'Write a thank-you email' },\
&#x20;   response\_mode: 'streaming',\
&#x20;   user: 'user-abc-123'\
&#x20; },\
&#x20; {\
&#x20;   headers: {\
&#x20;     'Authorization': 'Bearer YOUR-SECRET-KEY',\
&#x20;     'Content-Type': 'application/json'\
&#x20;   }\
&#x20; }\
);\
console.log(response.data);

### Response (Blocking Mode)

{\
&#x20; "id": "msg-abc123",\
&#x20; "answer": "Dear valued customer...",\
&#x20; "created\_at": 1705395332,\
&#x20; "metadata": {\
&#x20;   "usage": {\
&#x20;     "prompt\_tokens": 45,\
&#x20;     "completion\_tokens": 128,\
&#x20;     "total\_tokens": 173,\
&#x20;     "total\_price": "0.000346",\
&#x20;     "currency": "USD"\
&#x20;   }\
&#x20; }\
}

&#x20;

## Conversational App API

For Chatbot and Agent — supports multi-turn conversation.

### Endpoint

POST <https://api.clickai.io/v1/chat-messages>

### Request Body

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Field</td><td valign="top">Type</td><td valign="top">Required</td><td valign="top">Description</td></tr><tr><td valign="top">inputs</td><td valign="top">object</td><td valign="top">❌</td><td valign="top">Input variables (only for new conversations)</td></tr><tr><td valign="top">query</td><td valign="top">string</td><td valign="top">✅</td><td valign="top">User's message</td></tr><tr><td valign="top">response_mode</td><td valign="top">string</td><td valign="top">✅</td><td valign="top">"streaming" or "blocking"</td></tr><tr><td valign="top">conversation_id</td><td valign="top">string</td><td valign="top">❌</td><td valign="top">Conversation ID (empty = create new)</td></tr><tr><td valign="top">user</td><td valign="top">string</td><td valign="top">✅</td><td valign="top">Unique user ID</td></tr><tr><td valign="top">files</td><td valign="top">array</td><td valign="top">❌</td><td valign="top">Attached files</td></tr></tbody></table>

&#x20;

### Example — cURL

curl --location --request POST '<https://api.clickai.io/v1/chat-messages>' \\\
&#x20; \--header 'Authorization: Bearer YOUR-SECRET-KEY' \\\
&#x20; \--header 'Content-Type: application/json' \\\
&#x20; \--data-raw '{\
&#x20;   "inputs": {},\
&#x20;   "query": "Hello, I need product support",\
&#x20;   "response\_mode": "streaming",\
&#x20;   "conversation\_id": "",\
&#x20;   "user": "user-abc-123"\
&#x20; }'

### Example — Python

import requests\
import json\
\
url = "<https://api.clickai.io/v1/chat-messages"\\>
headers = {\
&#x20;   'Authorization': 'Bearer YOUR-SECRET-KEY',\
&#x20;   'Content-Type': 'application/json',\
}\
data = {\
&#x20;   "inputs": {},\
&#x20;   "query": "Hello, I need product support",\
&#x20;   "response\_mode": "streaming",\
&#x20;   "conversation\_id": "",\
&#x20;   "user": "user-abc-123"\
}\
response = requests.post(url, headers=headers, data=json.dumps(data))\
print(response.text)

&#x20;

## Workflow App API

For Workflow — batch processing, pipeline execution.

### Endpoint

POST <https://api.clickai.io/v1/workflows/run>

### Example — cURL

curl --location --request POST '<https://api.clickai.io/v1/workflows/run>' \\\
&#x20; \--header 'Authorization: Bearer YOUR-SECRET-KEY' \\\
&#x20; \--header 'Content-Type: application/json' \\\
&#x20; \--data-raw '{\
&#x20;   "inputs": {\
&#x20;     "input\_text": "Analyze Q4 2024 sales data"\
&#x20;   },\
&#x20;   "response\_mode": "streaming",\
&#x20;   "user": "user-abc-123"\
&#x20; }'

&#x20;

## Managing conversation\_id

### Rules

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Scenario</td><td valign="top">Action</td><td valign="top">Notes</td></tr><tr><td valign="top">New conversation</td><td valign="top">conversation_id: "" (empty)</td><td valign="top">System creates new ID, returned in response</td></tr><tr><td valign="top">Continue conversation</td><td valign="top">conversation_id: "conv-xyz789"</td><td valign="top">Use ID from previous response</td></tr><tr><td valign="top">Change variables mid-session</td><td valign="top">Use Conversation Variables</td><td valign="top">inputs ignored when conversation_id exists</td></tr></tbody></table>

&#x20;

### Complete Flow Example

import requests\
import json\
\
BASE\_URL = "<https://api.clickai.io/v1"\\>
HEADERS = {\
&#x20;   'Authorization': 'Bearer YOUR-SECRET-KEY',\
&#x20;   'Content-Type': 'application/json',\
}\
\
\# Turn 1: Start new conversation\
resp1 = requests.post(f"{BASE\_URL}/chat-messages", headers=HEADERS,\
&#x20;   data=json.dumps({\
&#x20;       "inputs": {"language": "en"},\
&#x20;       "query": "I need help with warranty",\
&#x20;       "response\_mode": "blocking",\
&#x20;       "conversation\_id": "",\
&#x20;       "user": "user-001"\
&#x20;   })\
).json()\
conv\_id = resp1\["conversation\_id"]\
print(f"Bot: {resp1\['answer']}")\
\
\# Turn 2: Continue conversation\
resp2 = requests.post(f"{BASE\_URL}/chat-messages", headers=HEADERS,\
&#x20;   data=json.dumps({\
&#x20;       "inputs": {},\
&#x20;       "query": "How long is the warranty for product XYZ?",\
&#x20;       "response\_mode": "blocking",\
&#x20;       "conversation\_id": conv\_id,\
&#x20;       "user": "user-001"\
&#x20;   })\
).json()\
print(f"Bot: {resp2\['answer']}")

🚨 WARNING: When passing an existing \`conversation\_id\`, all \`inputs\` values are ignored. Only \`query\` is processed. Use \*\*Conversation Variables\*\* to change variables mid-session.

&#x20;

## Streaming vs Blocking Response

### Blocking Mode

·       Returns complete result when processing finishes

·       Suitable for: Backend processing, batch jobs

·       Default timeout: 60 seconds

### Streaming Mode (Recommended)

·       Returns incremental chunks via Server-Sent Events (SSE)

·       Suitable for: Real-time chat, better UX

·       No processing time limit

### SSE Event Types

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Event</td><td valign="top">Description</td></tr><tr><td valign="top">message</td><td valign="top">Response content (text chunk)</td></tr><tr><td valign="top">agent_message</td><td valign="top">Response from Agent mode</td></tr><tr><td valign="top">agent_thought</td><td valign="top">Agent reasoning process</td></tr><tr><td valign="top">message_file</td><td valign="top">File generated by AI</td></tr><tr><td valign="top">message_end</td><td valign="top">End of message, includes metadata</td></tr><tr><td valign="top">error</td><td valign="top">Error occurred during stream</td></tr><tr><td valign="top">ping</td><td valign="top">Keep-alive signal</td></tr></tbody></table>

&#x20;

### Processing SSE in JavaScript

const response = await fetch('<https://api.clickai.io/v1/chat-messages>', {\
&#x20; method: 'POST',\
&#x20; headers: {\
&#x20;   'Authorization': 'Bearer YOUR-SECRET-KEY',\
&#x20;   'Content-Type': 'application/json'\
&#x20; },\
&#x20; body: JSON.stringify({\
&#x20;   inputs: {},\
&#x20;   query: 'Hello',\
&#x20;   response\_mode: 'streaming',\
&#x20;   conversation\_id: '',\
&#x20;   user: 'user-001'\
&#x20; })\
});\
\
const reader = response.body.getReader();\
const decoder = new TextDecoder();\
\
while (true) {\
&#x20; const { done, value } = await reader.read();\
&#x20; if (done) break;\
&#x20; const chunk = decoder.decode(value);\
&#x20; const lines = chunk.split('\n');\
&#x20; for (const line of lines) {\
&#x20;   if (line.startsWith('data: ')) {\
&#x20;     const data = JSON.parse(line.slice(6));\
&#x20;     if (data.event === 'message') {\
&#x20;       process.stdout.write(data.answer);\
&#x20;     }\
&#x20;   }\
&#x20; }\
}

&#x20;

## File Upload API

POST <https://api.clickai.io/v1/files/upload>

curl --location --request POST '<https://api.clickai.io/v1/files/upload>' \\\
&#x20; \--header 'Authorization: Bearer YOUR-SECRET-KEY' \\\
&#x20; \--form 'file=@"/path/to/document.pdf"' \\\
&#x20; \--form 'user="user-abc-123"'

Use in chat with "files": \[{"type": "document", "transfer\_method": "local\_file", "upload\_file\_id": "file-abc123"}]

&#x20;

## Feedback API

POST <https://api.clickai.io/v1/messages/{message\\_id}/feedbacks>

{\
&#x20; "rating": "like",\
&#x20; "user": "user-abc-123",\
&#x20; "content": "Very helpful answer!"\
}

&#x20;

## Conversations API

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Action</td><td valign="top">Method</td><td valign="top">Endpoint</td></tr><tr><td valign="top">List conversations</td><td valign="top">GET</td><td valign="top">/v1/conversations?user=user-id&#x26;limit=20</td></tr><tr><td valign="top">Get messages</td><td valign="top">GET</td><td valign="top">/v1/messages?conversation_id=conv-id&#x26;user=user-id</td></tr><tr><td valign="top">Rename</td><td valign="top">POST</td><td valign="top">/v1/conversations/{id}/name</td></tr><tr><td valign="top">Delete</td><td valign="top">DELETE</td><td valign="top">/v1/conversations/{id}</td></tr></tbody></table>

&#x20;

&#x20;

## Error Handling

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Code</td><td valign="top">Description</td></tr><tr><td valign="top">200</td><td valign="top">Success</td></tr><tr><td valign="top">400</td><td valign="top">Bad Request</td></tr><tr><td valign="top">401</td><td valign="top">Unauthorized — Invalid API Key</td></tr><tr><td valign="top">403</td><td valign="top">Forbidden</td></tr><tr><td valign="top">404</td><td valign="top">Not Found</td></tr><tr><td valign="top">429</td><td valign="top">Rate limit exceeded</td></tr><tr><td valign="top">500</td><td valign="top">Internal Server Error</td></tr></tbody></table>

&#x20;

&#x20;

## Rate Limits

<table data-header-hidden><thead><tr><th valign="top"></th><th valign="top"></th><th valign="top"></th></tr></thead><tbody><tr><td valign="top">Plan</td><td valign="top">Requests/min</td><td valign="top">Requests/day</td></tr><tr><td valign="top">Sandbox</td><td valign="top">100</td><td valign="top">10,000</td></tr><tr><td valign="top">Professional</td><td valign="top">500</td><td valign="top">100,000</td></tr><tr><td valign="top">Team</td><td valign="top">1,000</td><td valign="top">500,000</td></tr><tr><td valign="top">Enterprise</td><td valign="top">Custom</td><td valign="top">Custom</td></tr></tbody></table>

&#x20;

&#x20;

## SDK & Libraries

### Python SDK

from clickai import ClickAI\
\
client = ClickAI(api\_key="YOUR-SECRET-KEY")\
response = client.chat.create(query="Hello", user="user-001")\
print(response.answer)

### JavaScript SDK

import { ClickAI } from '@clickai/sdk';\
\
const client = new ClickAI({ apiKey: 'YOUR-SECRET-KEY' });\
const response = await client.chat.create({\
&#x20; query: 'Hello',\
&#x20; user: 'user-001'\
});\
console.log(response.answer);

&#x20;

*📖 See also: \[MCP Server]\(./02-mcp-server-en.md) · \[Build]\(../en/01-build-en.md)*
