Docs

📚 Code Examples

This comprehensive guide provides practical code examples for all Sentor ML API use cases.

🔑 Authentication

All examples require an API key. Set it as an environment variable:

export SENTOR_API_KEY="your-api-key-here"

📊 Sentiment Analysis

Single Document (English)

curl -X POST 'https://sentor.app/api/predicts' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{
  "docs": [
    {
      "doc_id": "doc1",
      "doc": "Apple'''s new iPhone is amazing!",
      "entities": ["Apple", "iPhone"]
    }
  ]
}'

Single Document (Dutch)

curl -X POST 'https://sentor.app/api/predicts?language=nl' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{
  "docs": [
    {
      "doc_id": "doc1",
      "doc": "De nieuwe Apple iPhone is geweldig!",
      "entities": ["Apple", "iPhone"]
    }
  ]
}'

Batch Processing

Process multiple documents in a single request:

curl -X POST 'https://sentor.app/api/predicts' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{
  "docs": [
    {
      "doc_id": "review1",
      "doc": "The camera quality is excellent, but battery life is disappointing.",
      "entities": ["camera quality", "battery life"]
    },
    {
      "doc_id": "review2",
      "doc": "Great build quality and fast performance!",
      "entities": ["build quality", "performance"]
    },
    {
      "doc_id": "review3",
      "doc": "Customer support was very helpful.",
      "entities": ["customer support"]
    }
  ]
}'

Response:

{
  "results": [
    {
      "doc_id": "review1",
      "predicted_class": 1,
      "predicted_label": "neutral",
      "probabilities": {
        "negative": 0.35,
        "neutral": 0.45,
        "positive": 0.20
      },
      "details": [...]
    },
    {
      "doc_id": "review2",
      "predicted_class": 2,
      "predicted_label": "positive",
      "probabilities": {
        "negative": 0.001,
        "neutral": 0.009,
        "positive": 0.99
      },
      "details": [...]
    }
  ]
}

🎯 Document Clustering

Basic Clustering Example

Cluster documents to find natural groupings:

curl -X POST 'https://sentor.app/api/predicts/cluster' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{
  "documents": [
    {
      "doc_id": "tech1",
      "text": "Apple announced new iPhone features with improved camera.",
      "entities": ["Apple", "iPhone", "camera"]
    },
    {
      "doc_id": "tech2",
      "text": "Samsung launched Galaxy with advanced AI capabilities.",
      "entities": ["Samsung", "Galaxy", "AI"]
    },
    {
      "doc_id": "tech3",
      "text": "Apple plans to integrate AI into iOS ecosystem.",
      "entities": ["Apple", "AI", "iOS"]
    },
    {
      "doc_id": "space1",
      "text": "SpaceX successfully launched Starlink satellites.",
      "entities": ["SpaceX", "Starlink", "satellites"]
    },
    {
      "doc_id": "finance1",
      "text": "Bitcoin price surged after ETF approval.",
      "entities": ["Bitcoin", "ETF"]
    }
  ]
}'

Response:

{
  "total_clusters": 3,
  "min_clusters": 2,
  "outliers": 0,
  "clusters": [
    {
      "cluster_id": 0,
      "documents": [
        {
          "doc_id": "tech1",
          "text": "Apple announced new iPhone features with improved camera.",
          "entities": ["Apple", "iPhone", "camera"],
          "cluster_probability": 0.92
        },
        {
          "doc_id": "tech3",
          "text": "Apple plans to integrate AI into iOS ecosystem.",
          "entities": ["Apple", "AI", "iOS"],
          "cluster_probability": 0.88
        }
      ],
      "top_words": ["apple", "iphone", "ios", "features", "ai"],
      "entities": ["Apple", "iPhone", "iOS", "AI"]
    },
    {
      "cluster_id": 1,
      "documents": [
        {
          "doc_id": "tech2",
          "text": "Samsung launched Galaxy with advanced AI capabilities.",
          "entities": ["Samsung", "Galaxy", "AI"],
          "cluster_probability": 0.85
        }
      ],
      "top_words": ["samsung", "galaxy", "ai", "advanced"],
      "entities": ["Samsung", "Galaxy", "AI"]
    }
  ]
}

🏷️ Topic Naming

Generate Topic Names for Clusters

After clustering, generate descriptive names:

curl -X POST 'https://sentor.app/api/predicts/topic-name' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{
  "cluster_id": 0,
  "documents": [
    {
      "doc_id": "tech1",
      "text": "Apple announced new iPhone features with improved camera.",
      "entities": ["Apple", "iPhone", "camera"],
      "cluster_probability": 0.92
    },
    {
      "doc_id": "tech3",
      "text": "Apple plans to integrate AI into iOS ecosystem.",
      "entities": ["Apple", "AI", "iOS"],
      "cluster_probability": 0.88
    }
  ],
  "entities": ["Apple", "iPhone", "iOS", "AI"],
  "top_words": ["apple", "iphone", "ios", "features", "ai", "ecosystem"]
}'

Response:

{
  "cluster_id": 0,
  "topic_name": "Apple iPhone and iOS Technology Updates",
  "generated_using": "company_key"
}

🔄 Complete Workflow

End-to-End: Predict → Cluster → Name

A complete example combining all three endpoints:

Step 1: Analyze Sentiment

PREDICT_RESPONSE=$(curl -X POST 'https://sentor.app/api/predicts' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{"docs": [...]}'
)

Step 2: Cluster Results

CLUSTER_RESPONSE=$(curl -X POST 'https://sentor.app/api/predicts/cluster' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{
    "documents": [...processed results from step 1...]
  }'
)

Step 3: Generate Topic Names (Parallel)

# Process each cluster in parallel
for cluster in $(echo $CLUSTER_RESPONSE | jq -c '.clusters[]'); do
  curl -X POST 'https://sentor.app/api/predicts/topic-name' 
    -H 'x-api-key: YOUR_API_KEY' 
    -H 'Content-Type: application/json' 
    -d "$cluster" &
done
wait

⚠️ Error Handling

Handle Rate Limits

response=$(curl -s -w "\n%{http_code}" -X POST 'https://sentor.app/api/predicts' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{"docs": [...]}')

http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')

if [ "$http_code" -eq 429 ]; then
  retry_after=$(echo "$body" | jq -r '.error.details.retry_after')
  echo "Rate limit exceeded. Retry after $retry_after seconds"
  sleep $retry_after
  # Retry request
fi

Handle Invalid Requests

response=$(curl -s -X POST 'https://sentor.app/api/predicts' 
  -H 'x-api-key: YOUR_API_KEY' 
  -H 'Content-Type: application/json' 
  -d '{"docs": [...]}')

if echo "$response" | jq -e '.error' > /dev/null; then
  error_code=$(echo "$response" | jq -r '.error.code')
  error_message=$(echo "$response" | jq -r '.error.message')
  echo "Error $error_code: $error_message"
  exit 1
fi

🐍 Python SDK Examples

Basic Usage

from sentor import SentorClient

# Initialize client
client = SentorClient('YOUR_API_KEY')

# Analyze sentiment
input_data = [
  {
    "doc": "Apple's new iPhone is amazing!",
    "doc_id": "doc1",
    "entities": ["Apple", "iPhone"]
  }
]

result = client.analyze(input_data)
print(f"Sentiment: {result['results'][0]['predicted_label']}")

Clustering Example

from sentor import SentorClient

client = SentorClient('YOUR_API_KEY')

# Prepare documents
documents = [
  {
    "doc_id": f"doc{i}",
    "text": text,
    "entities": entities
  }
  for i, (text, entities) in enumerate(your_data, 1)
]

# Cluster documents
clustering_result = client.cluster(documents, language='en')

# Generate topic names for each cluster
topic_names = []
for cluster in clustering_result['clusters']:
    topic_result = client.generate_topic_name(
        cluster_id=cluster['cluster_id'],
        documents=cluster['documents'],
        entities=cluster['entities'],
        top_words=cluster['top_words']
    )
    topic_names.append(topic_result['topic_name'])
    print(f"Cluster {cluster['cluster_id']}: {topic_result['topic_name']}")

Error Handling

from sentor import SentorClient
from sentor.exceptions import SentorAPIError, RateLimitError
import time

client = SentorClient('YOUR_API_KEY')

def analyze_with_retry(data, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.analyze(data)
        except RateLimitError as e:
            if attempt < max_retries - 1:
                print(f"Rate limit hit. Waiting {e.retry_after} seconds...")
                time.sleep(e.retry_after)
            else:
                raise
        except SentorAPIError as e:
            print(f"API Error: {e.message}")
            raise

# Use it
result = analyze_with_retry(your_data)

💻 JavaScript/TypeScript SDK Examples

Basic Usage

import { SentorClient } from 'sentor-sdk';

// Initialize client
const client = new SentorClient('YOUR_API_KEY');

// Analyze sentiment
const input = {
  docs: [
    {
      doc: "Apple's new iPhone is amazing!",
      doc_id: "doc1",
      entities: ["Apple", "iPhone"]
    }
  ]
};

const result = await client.analyze(input);
console.log(`Sentiment: ${result.results[0].predicted_label}`);

Clustering and Topic Naming

import { SentorClient } from 'sentor-sdk';

const client = new SentorClient('YOUR_API_KEY');

// Cluster documents
const documents = [
  {
    doc_id: "tech1",
    text: "Apple announced new iPhone features.",
    entities: ["Apple", "iPhone"]
  },
  // ... more documents
];

const clusterResult = await client.cluster({ documents }, 'en');

// Generate topic names in parallel
const topicPromises = clusterResult.clusters.map(cluster =>
  client.generateTopicName({
    cluster_id: cluster.cluster_id,
    documents: cluster.documents,
    entities: cluster.entities,
    top_words: cluster.top_words
  })
);

const topicResults = await Promise.all(topicPromises);
topicResults.forEach(topic => {
  console.log(`Cluster ${topic.cluster_id}: ${topic.topic_name}`);
});

Error Handling

import { SentorClient, SentorAPIError, RateLimitError } from 'sentor-sdk';

const client = new SentorClient('YOUR_API_KEY');

async function analyzeWithRetry(data: any, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.analyze(data);
    } catch (error) {
      if (error instanceof RateLimitError && attempt < maxRetries - 1) {
        console.log(`Rate limit hit. Waiting ${error.retryAfter} seconds...`);
        await new Promise(resolve => 
          setTimeout(resolve, error.retryAfter * 1000)
        );
      } else if (error instanceof SentorAPIError) {
        console.error(`API Error ${error.code}: ${error.message}`);
        throw error;
      } else {
        throw error;
      }
    }
  }
}

// Use it
const result = await analyzeWithRetry(yourData);

📝 Best Practices

  1. Batch Processing: Send multiple documents in one request to optimize API usage
  2. Rate Limit Handling: Implement exponential backoff for rate limit errors
  3. Error Handling: Always wrap API calls in try-catch blocks
  4. Parallel Processing: Process topic naming for multiple clusters in parallel
  5. Caching: Cache sentiment results for identical documents to reduce API calls
  6. Language Specification: Always specify the language parameter for non-English content

🔗 Related Resources

💬 Support