Prose Captain
Prose Captain integration
Add the AI assistant to your site in a few simple steps.
1. Configuration
Before installing Prose Captain on your site, configure your account and collect the details you need. Follow these step-by-step instructions.
Get your token
To get a unique token for your site:
- Sign in to your account at prosecaptain.com
- Open User profile
- In the "API tokens" section you will find your unique token ID
- Copy the token and save it—you will need it when installing the widget.
AI settings
You can customize the AI assistant by adding instructions and prompts. To do that:
- Sign in to the Prose Captain admin panel
- Go to the "Artificial Intelligence Settings" section.
- In the "Prompt Template" section you can tailor instructions for your assistant
- Enter instructions that define what the assistant should know and how it should communicate
- Save your changes using the "Save" button
Tip
A well-written prompt can greatly improve answer quality. Include concrete guidance on personality, tone, and scope of knowledge.
Language preferences
Prose Captain supports multiple languages from the admin panel. To set your preferred language:
- Sign in to the admin panel
- Open the "Widget Settings" section
- Choose your preferred language from the available options (e.g. Polish or English)
- Save your preferences
That language is used in the widget UI and influences the assistant default reply language.
Adding the script
Paste the following snippet in your page <head>
head section:
<script
src="https://widget-api.example.com/embed.js"
data-widget-token="YOUR_TOKEN_HERE"
data-theme="light"
></script>
Script parameters
data-widget-token
Your unique widget access token. Use the token from the admin panel.
data-theme
Widget theme: "light" or "dark"
data-api-url
Base URL for the Prose Captain API
3. Advanced configuration
For advanced users, Prose Captain supports integrating your own applications via the API and extra personalization options. Below are additional ways to tailor and connect.
3.1. User context
When you start a new chat session you can send user context so the assistant better understands needs and tailors replies. Context may include:
- User data (e.g. first name, user id)
- Information about the current page or category
- Preferences and interests
- Browsing history
- Other custom data fields
To send user context, add a context
property to the JSON body when creating a new session:
// Sample user context object
const userContext = {
user_id: "user_12345", // Prefer an opaque ID instead of full PII
first_name: "Alex", // First name only, not a full legal name
viewed_categories: ["footwear", "sport", "electronics"],
current_page: "Category: Sports",
preferences: {
favorite_colors: ["blue", "green"],
interests: ["running", "mountain biking", "photography"]
},
visit_history: {
last_visit: "2023-09-15T14:30:00Z",
visit_count: 12
}
};
When creating a new session, include that object in the request body:
// Create a new session with user context
fetch('https://widget-api.example.com/api/widget/thread?token=YOUR_TOKEN_HERE', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
context: userContext
})
})
.then(response => response.json())
.then(data => {
console.log('Session created:', data.session_id);
});
Data privacy
Do not send sensitive personal data such as full legal name, email, phone number, or street address. Prefer identifiers, pseudonyms, or partial data.
3.2. API Endpoints
Below are the endpoints you can use for deeper Prose Captain integrations in your app:
Create a new chat session
https://widget-api.example.com/api/widget/thread?token=YOUR_TOKEN_HERE
Creates a chat, returns the session id and message history including the assistant welcome message.
Parameters
token (query) -
Widget token Response
{
"session_id": "session_xyz789",
"history": [
{
"role": "assistant",
"content": "Hello! I am your AI assistant. How can I help you today?"
}
]
}
Widget Message Endpoint
Sends the user message and returns the assistant reply. If the session_id does not exist, the API creates a session, returns its id, and includes the welcome message in history.
https://widget-api.example.com/api/widget/message?token=YOUR_TOKEN_HERE
Sends the user message and returns the assistant AI reply.
Body (JSON)
{
"session_id": "session_xyz789",
"message": "Your message here"
}
Response for an existing session
{
"response": "Assistant reply to your message"
}
Response when the session does not exist
{
"response": "Assistant reply to your message",
"session_id": "new_session_abc123",
"history": [
{
"role": "assistant",
"content": "Hello! I am your AI assistant. How can I help you today?"
},
{
"role": "user",
"content": "Your message here"
},
{
"role": "assistant",
"content": "Assistant reply to your message"
}
]
}
Note: The response field contains the same text as the last element in the history. array. This is intentional so clients can use that value without scanning history for the last assistant message.
Chat history
https://widget-api.example.com/api/widget/chat-history?token=YOUR_TOKEN_HERE&session_id=SESSION_ID
Loads message history for a chat session.
Parameters
token (query) -
Widget token session_id (query) -
Session identifier page (query,
optional) - Page number (default 1) limit (query,
optional) - Messages per page (default 50) Response
{
"messages": [
{
"id": "msg_123abc",
"role": "user",
"content": "Hi, how are you?",
"timestamp": "2023-03-30T14:30:45Z"
},
{
"id": "msg_456def",
"role": "assistant",
"content": "Hello! I am doing well, thank you for asking. How can I help you today?",
"timestamp": "2023-03-30T14:30:50Z"
}
],
"meta": {
"total": 2,
"page": 1,
"limit": 50
}
}
Workspace information
https://widget-api.example.com/api/widget/workspace?token=YOUR_TOKEN_HERE
Returns basic information about the workspace.
Parameters
token (query) -
Widget token Response
{
"name": "Workspace name",
"organisation": "Organization name"
}
3.4. API limits and error handling
API limits and common error payloads you may see while integrating.
Limits
Maximum message length
500 characters
Session requirements
Endpoint /message requires a valid session_id. When the provided session_id does not exist, a new session is created.
Common errors
| Status | Error | Description |
|---|---|---|
| 400 | Session ID is required | The request is missing a session identifier |
| 400 | Message is required | The request is missing message content |
| 400 | Message is too long | Message exceeds the maximum length (500 characters) |
| 404 | Workspace not found | Invalid widget token |
| 429 | Rate limit exceeded | Too many requests in a short time window |
| 500 | Server error occurred | Internal server error |
Sample error response
{
"error": "Message is too long. Maximum allowed length is 500 characters."
}
3.3. Sample integration
Below is a sample JavaScript integration with user context.
// Sample user context object
const userContext = {
user_id: "user_12345",
first_name: "Alex",
current_page: "Category: Sports",
viewed_categories: ["footwear", "sport", "electronics"],
preferences: {
interests: ["running", "mountain biking"]
}
};
// Initialize chat with optional user context
const initChat = async (context = null) => {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
// Add context to the JSON body when provided
if (context) {
options.body = JSON.stringify({ context });
}
const response = await fetch('https://widget-api.example.com/api/widget/thread?token=YOUR_TOKEN_HERE', options);
const data = await response.json();
return data.session_id;
};
// Send a user message to the widget API
const sendMessage = async (sessionId, message) => {
const response = await fetch('https://widget-api.example.com/api/widget/message?token=YOUR_TOKEN_HERE', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
session_id: sessionId,
message: message
})
});
return await response.json();
};
// Usage example
(async () => {
// Create a new session with user context
const sessionId = await initChat(userContext);
console.log('Session created with context:', sessionId);
// Send a message in that session
const response = await sendMessage(sessionId, 'Show me available running shoe models');
console.log('Assistant reply:', response.response);
})();
Tip
In production, add error handling and retry logic for network failures. Tune user context to your app so it only includes signals that help the assistant answer.
4. Article Generation API
Generate AI-powered articles programmatically. Create drafts, full articles with sources, and publish directly to WordPress.
Authentication
All Article API endpoints require a Directus Bearer token in the Authorization header:
Authorization: Bearer YOUR_DIRECTUS_TOKEN
Get your token from the Directus admin panel under User Settings → Token.
Base URL: https://widget-api.example.com
Generate article draft
https://widget-api.example.com/api/draft
Creates an article structure/outline. Returns EditorJS blocks and a threadId required for full article generation.
Request body (JSON)
{
"articleId": "uuid-of-article",
"context": "Article topic or brief description",
"keywords": ["keyword1", "keyword2", "keyword3"],
"toneOfVoice": "casual",
"complexity": "fog index: 15",
"language": "polski",
"contentType": "blogpost",
"includeImages": true
}
Parameters
articleId * - UUID of article record in Directus context * - Topic or brief for the article keywords - Array of up to 3 keywords toneOfVoice - Writing style: casual, formal, professional (default: casual) complexity - Reading level, e.g. "fog index: 15" (default: fog index: 15) language - Output language: polski, english, etc. (default: polski) contentType - Article type: blogpost, summary, changelog (default: blogpost) includeImages - Generate thumbnail image (default: true) Response
{
"success": true,
"draft": {
"blocks": [
{ "type": "header", "data": { "text": "Article Title", "level": 1 } },
{ "type": "paragraph", "data": { "text": "Introduction paragraph..." } }
]
},
"threadId": "thread_abc123xyz",
"article": { /* full article record */ }
}
Cost: 1 credit. Timeout: 10 minutes.
Generate full article
https://widget-api.example.com/api/article
Expands the draft into a complete article. Requires a draft to be generated first.
Request body (JSON)
{
"articleId": "uuid-of-article",
"threadId": "thread_abc123xyz"
}
Parameters
articleId * - UUID of article (must have a draft) threadId * - Thread ID returned from /api/draft Cost: 2 credits. Timeout: 20 minutes.
Important
After generation, the system automatically creates SEO metadata (title, description) and FAQ sections.
Adding sources
Sources are stored in Directus as M2M relations. When creating an article record, link sources using:
articles_articles_sources
Junction table linking articles to source articles from your knowledge base.
articles_linked_source
Direct URL references to external sources.
The AI will automatically incorporate these sources when generating content.
Post-processing endpoints
Optional endpoints to regenerate or enhance article components:
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/faq | Regenerate FAQ section |
| POST | /api/metadata | Regenerate SEO title and meta description |
| POST | /api/regenerate-thumbnail | Generate new thumbnail (Pexels or Gemini) |
| POST | /api/keywords | Suggest keywords for article |
All endpoints require articleId in the request body.
Send to WordPress
https://widget-api.example.com/api/send-to-wp
Publishes the article to your connected WordPress site. Converts EditorJS blocks to HTML and creates a new post.
Request body (JSON)
{
"articleId": "uuid-of-article"
}
Note: WordPress credentials must be configured in the workspace settings. Contact support if you need help connecting your site.
Errors and limits
Rate limits
AI generation endpoints: 10 requests per minute per workspace.
Common errors
| Status | Error | Solution |
|---|---|---|
| 401 | Unauthorized | Check your Directus token |
| 402 | Insufficient credits | Add more credits to your workspace |
| 400 | Missing threadId | Generate a draft first to get threadId |
| 404 | Article not found | Verify articleId exists in Directus |
| 429 | Rate limit exceeded | Wait 1 minute before retrying |
| 504 | Generation timeout | Article may be too complex; try with shorter context |
Article status reference
| Status | Meaning |
|---|---|
| draft | Article record created, no content yet |
| ongoing | Generation in progress |
| success | Article ready (FAQ or thumbnail may be missing) |
| done | Fully complete with FAQ and thumbnail |
| failed | Generation failed |