> 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)*


---

# 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 dynamically by asking a question.

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

```
GET https://docs.clickai.vn/clickai-docs/clickai-docs-en/developer/integrate-clickai-via-restful-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
