API Dashboard

Developer Tools

API Documentation

Complete guide to integrate Open Spoken AI into your applications

Authentication

Authenticate your API requests using your API key

Include your API key in the Authorization header of every request:

Authorization: Bearer YOUR_API_KEY

Endpoints

POST/api/v1/generate

Generate content using AI templates or freestyle

promptstringrequired- Your content request
templatestringoptional- Template code (see list below)
optionsobjectoptional- Template-specific options
max_tokensnumberoptional- Max output tokens (default: 1000)
GET/api/v1/balance

Get your current balance and usage stats

GET/api/v1/templates

List all available templates with their options

GET/api/v1/logs

Get request history with pagination and filtering

Response Format

Standard API response structure

Success Response (200 OK):

{
  "success": true,
  "data": {
    "content": "🧘‍♀️ Yoga instructor | Flow & flexibility...",
    "template_used": "bio-instagram"
  },
  "usage": {
    "input_tokens": 366,
    "output_tokens": 50,
    "total_tokens": 416,
    "cost_usd": 0.0054
  },
  "balance": {
    "remaining": 24.99
  }
}

Error Response:

{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Insufficient balance to complete request"
  }
}

Error Codes

Possible error responses and their meanings

401
INVALID_API_KEY

API key is missing, invalid, or revoked

402
INSUFFICIENT_BALANCE

Not enough balance to complete this request

429
RATE_LIMIT_EXCEEDED

Too many requests (max 10 per minute)

400
INVALID_TEMPLATE

Template code not found or invalid

400
VALIDATION_ERROR

Invalid or missing required parameters

500
GENERATION_FAILED

AI generation failed, please retry

500
BILLING_FAILED

Failed to deduct balance, please contact support

Code Examples

Quick start examples in multiple languages

curl -X POST https://textly.openspoken.ai/api/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Write a flirty bio for a yoga instructor",
    "template": "bio-instagram",
    "options": {
      "tone": "flirty",
      "include_emojis": true
    },
    "max_tokens": 200
  }'

Error Handling

Best practices for handling API errors

Always check the success field and handle errors gracefully:

Python:

import requests
import time

try:
    response = requests.post(url, headers=headers, json=data)
    result = response.json()
    
    if result.get("success"):
        print(result["data"]["content"])
    else:
        error = result.get("error", {})
        if error.get("code") == "INSUFFICIENT_BALANCE":
            print("⚠️ Low balance! Add funds at /api-dashboard/billing")
        elif error.get("code") == "RATE_LIMIT_EXCEEDED":
            print("⏳ Rate limit hit, waiting 60 seconds...")
            time.sleep(60)
        else:
            print(f"Error: {error.get('message')}")
            
except requests.exceptions.RequestException as e:
    print(f"Network error: {e}")

Node.js:

async function generateContent(prompt) {
  try {
    const response = await fetch(url, { 
      method: 'POST', 
      headers, 
      body: JSON.stringify({ prompt }) 
    });
    
    const data = await response.json();
    
    if (!data.success) {
      const errorCode = data.error?.code;
      
      if (errorCode === 'INSUFFICIENT_BALANCE') {
        throw new Error('Low balance. Add funds to continue.');
      } else if (errorCode === 'RATE_LIMIT_EXCEEDED') {
        // Retry after 60 seconds
        await new Promise(resolve => setTimeout(resolve, 60000));
        return generateContent(prompt); // Retry
      } else {
        throw new Error(data.error?.message || 'Unknown error');
      }
    }
    
    return data.data.content;
    
  } catch (error) {
    console.error('API Error:', error.message);
    throw error;
  }
}

💡 Best Practices:

  • Always check success field before accessing data
  • Implement retry logic for RATE_LIMIT_EXCEEDED
  • Monitor balance and show warnings at $5 threshold
  • Log errors with request IDs for debugging
  • Use exponential backoff for transient errors (500)

Request Logs & Filtering

Retrieve and filter request history with pagination

The /api/v1/logs endpoint supports pagination and filtering:

limitnumber- Number of records (max 100, default 50)
offsetnumber- Records to skip (default 0)
request_idstring- Filter by specific request ID (returns all matching logs)
templatestring- Filter by template code
start_datestring- Filter from date (ISO 8601)
end_datestring- Filter to date (ISO 8601)

Example Request (with filters):

# Get all logs with request_id "campaign-001"
curl -X GET "https://textly.openspoken.ai/api/v1/logs?request_id=campaign-001" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by template
curl -X GET "https://textly.openspoken.ai/api/v1/logs?template=bio-instagram&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

{
  "success": true,
  "logs": [
    {
      "request_id": "campaign-001",
      "template": "bio-instagram",
      "prompt": "Write a flirty bio for a yoga instructor",
      "response": "🧘‍♀️ Yoga instructor | Flow & flexibility...",
      "input_tokens": 366,
      "output_tokens": 50,
      "total_tokens": 416,
      "cost_usd": 0.0054,
      "generation_time_ms": 1250,
      "webhook_url": "https://example.com/webhook",
      "webhook_status": "success",
      "created_at": "2026-01-07T10:30:00Z"
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "total": 1,
    "has_more": false
  }
}

💡 Request ID Usage:

Use request_id as a batch identifier to group related generations. For example, use "campaign-black-friday" for all content in that campaign. The API will return ALL logs matching that request_id (not just one).

⚠️ Empty Results:

If no logs match your filters, you'll receive an empty array with total: 0 (not an error). This allows consistent response handling in your code.

Available Templates

Get full list via GET /api/v1/templates endpoint

Call /api/v1/templates to get all 40+ templates with their options.

Popular templates:

bio-twitterTwitter/X Bio
tonelength
bio-instagramInstagram Bio
toneinclude_emojis
ppv-messagePPV Message
tonelength
post-captionSocial Media Caption
toneinclude_hashtagsinclude_call_to_action
sexting-scriptSexting Script
toneintensity
promo-textPromotional Text
toneinclude_discount

Pricing & Balance

Token-based pricing with shared balance

Input Tokens
$8
per 1M tokens
Output Tokens
$50
per 1M tokens

💡 Shared Balance: Your balance is shared across all API keys. Add funds once, use everywhere.

Rate Limits

Default limits for all API keys

Requests per minute:10
Max prompt length:10,000 characters
Max tokens per request:5,000