Public API Documentation
Base URL: https://kontentspace.com/api/public-service
Authentication
All endpoints require an API key passed via the Authorization header:
Authorization: Bearer ks_live_your_api_key_here
API keys can be created in the Settings > API Keys page (requires Pro plan or higher).
Response Format
All responses follow a consistent JSON format:
Success:
{
"success": true,
"data": { ... }
}
Error:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message"
}
}
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid API key |
BAD_REQUEST | 400 | Invalid JSON body |
VALIDATION_ERROR | 400 | Request body failed validation |
NOT_FOUND | 404 | Resource not found |
SUBSCRIPTION_REQUIRED | 403 | Active subscription required |
USAGE_LIMIT_EXCEEDED | 403 | Tweet or storage limit exceeded |
STORAGE_LIMIT_EXCEEDED | 403 | Storage quota exceeded |
TWITTER_ERROR | 500 | Twitter API error |
SERVER_ERROR | 500 | Internal server error |
Twitter Endpoints
Post a Tweet
Post a single tweet to your connected Twitter account.
POST /twitter/tweet
Request Body:
{
"text": "Hello from the API!",
"mediaBase64": ["data:image/png;base64,..."] // optional
}
| Field | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Tweet content (1-280 characters) |
mediaBase64 | string[] | No | Array of base64-encoded images |
Response:
{
"success": true,
"data": {
"id": "1234567890",
"text": "Hello from the API!"
}
}
Example:
curl -X POST https://kontentspace.com/api/public-service/twitter/tweet \
-H "Authorization: Bearer ks_live_..." \
-H "Content-Type: application/json" \
-d '{"text": "Hello from the API!"}'
Post a Thread
Post a thread of connected tweets.
POST /twitter/thread
Request Body:
{
"tweets": [
{ "text": "First tweet in the thread" },
{ "text": "Second tweet continues here" },
{ "text": "Final tweet!", "mediaBase64": ["..."] }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
tweets | array | Yes | Array of tweet objects (min 1) |
tweets[].text | string | Yes | Tweet content (1-280 characters) |
tweets[].mediaBase64 | string[] | No | Array of base64-encoded images |
Response:
{
"success": true,
"data": [
{ "id": "1234567890", "text": "First tweet in the thread" },
{ "id": "1234567891", "text": "Second tweet continues here" },
{ "id": "1234567892", "text": "Final tweet!" }
]
}
Get Timeline
Fetch recent tweets from your timeline.
GET /twitter/timeline?maxResults=10
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
maxResults | number | 10 | Number of tweets to fetch (1-100) |
Response:
{
"success": true,
"data": {
"tweets": [
{
"id": "1234567890",
"text": "Tweet content here",
"created_at": "2024-01-15T10:30:00.000Z"
}
]
}
}
Get Twitter Accounts
Get all connected Twitter accounts and the currently active one.
GET /twitter/accounts
Response:
{
"success": true,
"data": {
"connected": true,
"activeAccount": {
"id": "acc_123",
"username": "myhandle",
"name": "My Name"
},
"accounts": [
{
"id": "acc_123",
"username": "myhandle",
"name": "My Name"
}
]
}
}
Set Active Twitter Account
Switch the active Twitter account for posting.
POST /twitter/accounts/active
Request Body:
{
"accountId": "acc_123"
}
| Field | Type | Required | Description |
|---|---|---|---|
accountId | string | null | Yes | Account ID to set as active, or null to clear |
Posts Endpoints
Manage drafts and scheduled posts.
List Posts
GET /posts?status=SCHEDULED
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: DRAFT, SCHEDULED, PUBLISHING, PUBLISHED, FAILED |
Response:
{
"success": true,
"data": [
{
"id": "post_123",
"content": "My scheduled tweet",
"status": "SCHEDULED",
"scheduledAt": "2024-01-20T15:00:00.000Z",
"mediaUrls": [],
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-15T10:00:00.000Z"
}
]
}
Create Post
POST /posts
Request Body:
{
"content": "My tweet content",
"status": "SCHEDULED",
"scheduledAt": "2024-01-20T15:00:00.000Z",
"mediaUrls": []
}
| Field | Type | Required | Description |
|---|---|---|---|
content | string | Yes | Post content (min 1 character) |
status | string | No | DRAFT, SCHEDULED, or PUBLISHED (default: DRAFT or SCHEDULED if time provided) |
scheduledAt | string | No | ISO 8601 UTC datetime for scheduling |
scheduledLocal | string | No | Local datetime YYYY-MM-DDTHH:mm (uses your timezone setting) |
mediaUrls | string[] | No | Array of media URLs |
tweetId | string | No | Associated tweet ID if already published |
Response:
{
"success": true,
"data": {
"id": "post_123",
"content": "My tweet content",
"status": "SCHEDULED",
"scheduledAt": "2024-01-20T15:00:00.000Z",
"publishedAt": null,
"mediaUrls": [],
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-15T10:00:00.000Z"
}
}
Update Post
POST /posts/update
Request Body:
{
"id": "post_123",
"content": "Updated content",
"status": "DRAFT"
}
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Post ID to update |
content | string | No | New content |
status | string | No | New status |
scheduledAt | string | null | No | New schedule time (null to clear) |
scheduledLocal | string | null | No | New local schedule time |
mediaUrls | string[] | No | New media URLs |
Delete Post
POST /posts/delete
Request Body:
{
"id": "post_123"
}
Learning Assets Endpoints
Manage uploaded files for AI context.
List Learning Assets
GET /learning-assets
Response:
{
"success": true,
"data": [
{
"id": "asset_123",
"fileName": "brand-guidelines.pdf",
"mimeType": "application/pdf",
"sizeBytes": 1048576,
"s3Key": "user_123/...",
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-15T10:00:00.000Z"
}
]
}
Upload Learning Asset
POST /learning-assets
Request Body:
{
"fileName": "style-guide.md",
"mimeType": "text/markdown",
"sizeBytes": 2048,
"base64": "IyBTdHlsZSBHdWlkZQ0K..."
}
| Field | Type | Required | Description |
|---|---|---|---|
fileName | string | Yes | File name (1-255 characters) |
mimeType | string | Yes | MIME type (1-255 characters) |
sizeBytes | number | Yes | File size in bytes (max 50MB) |
base64 | string | Yes | Base64-encoded file content |
Delete Learning Asset
POST /learning-assets/delete
Request Body:
{
"id": "asset_123"
}
Account Endpoints
Get Usage
Get current usage statistics and remaining quotas.
GET /usage
Response:
{
"success": true,
"data": {
"planName": "Pro",
"isSubscriptionActive": true,
"lastResetTime": "2024-01-01T00:00:00.000Z",
"nextResetTime": "2024-02-01T00:00:00.000Z",
"tweets": {
"remaining": 450,
"used": 50,
"limit": 500
},
"aiMessages": {
"remaining": 180,
"used": 20,
"limit": 200
},
"scheduledPosts": {
"used": 5,
"remaining": 45,
"limit": 50,
"unlimited": false
},
"storage": {
"usedBytes": 5242880,
"remainingBytes": 99614720,
"limitBytes": 104857600,
"unlimited": false
}
}
}
Get Timezone
GET /settings/timezone
Response:
{
"success": true,
"data": {
"timezone": "America/New_York",
"timezones": ["Africa/Abidjan", "Africa/Accra", "..."]
}
}
Update Timezone
POST /settings/timezone
Request Body:
{
"timezone": "America/New_York"
}
| Field | Type | Required | Description |
|---|---|---|---|
timezone | string | null | Yes | IANA timezone identifier, or null to clear |
Rate Limits
API keys are subject to rate limiting based on your plan:
- Rate limits are enforced per API key
- Tweet posting consumes from your monthly tweet quota
- AI message endpoints consume from your monthly AI quota
- Storage uploads count against your storage quota
Check your current usage with the GET /usage endpoint.
Example: Schedule a Tweet
# Create a scheduled post
curl -X POST https://kontentspace.com/api/public-service/posts \
-H "Authorization: Bearer ks_live_..." \
-H "Content-Type: application/json" \
-d '{
"content": "This tweet will be posted automatically!",
"scheduledLocal": "2024-01-20T15:00"
}'
Example: Post with Media
# Encode image to base64
IMAGE_BASE64=$(base64 -i photo.jpg)
# Post tweet with image
curl -X POST https://kontentspace.com/api/public-service/twitter/tweet \
-H "Authorization: Bearer ks_live_..." \
-H "Content-Type: application/json" \
-d "{
\"text\": \"Check out this photo!\",
\"mediaBase64\": [\"data:image/jpeg;base64,$IMAGE_BASE64\"]
}"