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

CodeHTTP StatusDescription
UNAUTHORIZED401Missing or invalid API key
BAD_REQUEST400Invalid JSON body
VALIDATION_ERROR400Request body failed validation
NOT_FOUND404Resource not found
SUBSCRIPTION_REQUIRED403Active subscription required
USAGE_LIMIT_EXCEEDED403Tweet or storage limit exceeded
STORAGE_LIMIT_EXCEEDED403Storage quota exceeded
TWITTER_ERROR500Twitter API error
SERVER_ERROR500Internal 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
}
FieldTypeRequiredDescription
textstringYesTweet content (1-280 characters)
mediaBase64string[]NoArray 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": ["..."] }
  ]
}
FieldTypeRequiredDescription
tweetsarrayYesArray of tweet objects (min 1)
tweets[].textstringYesTweet content (1-280 characters)
tweets[].mediaBase64string[]NoArray 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:

ParameterTypeDefaultDescription
maxResultsnumber10Number 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"
}
FieldTypeRequiredDescription
accountIdstring | nullYesAccount ID to set as active, or null to clear

Posts Endpoints

Manage drafts and scheduled posts.

List Posts

GET /posts?status=SCHEDULED

Query Parameters:

ParameterTypeDescription
statusstringFilter 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": []
}
FieldTypeRequiredDescription
contentstringYesPost content (min 1 character)
statusstringNoDRAFT, SCHEDULED, or PUBLISHED (default: DRAFT or SCHEDULED if time provided)
scheduledAtstringNoISO 8601 UTC datetime for scheduling
scheduledLocalstringNoLocal datetime YYYY-MM-DDTHH:mm (uses your timezone setting)
mediaUrlsstring[]NoArray of media URLs
tweetIdstringNoAssociated 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"
}
FieldTypeRequiredDescription
idstringYesPost ID to update
contentstringNoNew content
statusstringNoNew status
scheduledAtstring | nullNoNew schedule time (null to clear)
scheduledLocalstring | nullNoNew local schedule time
mediaUrlsstring[]NoNew 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..."
}
FieldTypeRequiredDescription
fileNamestringYesFile name (1-255 characters)
mimeTypestringYesMIME type (1-255 characters)
sizeBytesnumberYesFile size in bytes (max 50MB)
base64stringYesBase64-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"
}
FieldTypeRequiredDescription
timezonestring | nullYesIANA 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\"]
  }"