SDKs and Libraries
SDK and client library overview for the Builder API - links to official and community-supported libraries for integrating Synthreo AI agents into your applications.
Synthreo provides official SDKs and libraries to simplify integration with the Builder API. These SDKs implement all the best practices covered in our documentation, including authentication management, error handling, rate limiting, and webhook processing.
Official SDKs
Section titled “Official SDKs”Node.js SDK
Section titled “Node.js SDK”Installation:
npm install @synthreo/sdk
yarn add @synthreo/sdkQuick Start:
const { SynthreoClient } = require('@synthreo/sdk');
const client = new SynthreoClient({ email: process.env.SYNTHREO_API_EMAIL, password: process.env.SYNTHREO_API_PASSWORD, userId: parseInt(process.env.SYNTHREO_USER_ID), environment: 'production' // or 'development'});
// Simple executionconst response = await client.executeDiagram(12345, "Hello AI!");console.log(response.getAIResponse());
// Async job with automatic pollingconst jobResult = await client.executeAsJob(12345, "Process this data");console.log(jobResult.getOutput());Advanced Features:
const client = new SynthreoClient({ email: process.env.SYNTHREO_API_EMAIL, password: process.env.SYNTHREO_API_PASSWORD, userId: parseInt(process.env.SYNTHREO_USER_ID),
// Advanced configuration options: { // Rate limiting rateLimiting: { requestsPerMinute: 60, enableQueue: true, maxConcurrent: 5 },
// Polling configuration polling: { jobInterval: 30000, // 30 seconds trainingInterval: 60000, // 60 seconds timeout: 3600000 // 1 hour },
// Retry configuration retry: { maxAttempts: 3, baseDelay: 1000, exponentialBackoff: true },
// Caching caching: { enabled: true, tokenTTL: 86400000, // 24 hours responseTTL: 300000 // 5 minutes },
// Webhooks webhooks: { enabled: true, secret: process.env.WEBHOOK_SECRET, endpoint: '/webhooks/synthreo', fallbackToPolling: true } }});
// Execute with conversation contextconst result = await client.executeDiagram(12345, { message: "Follow up question", context: { conversationId: "conv-123", userId: "user-456", previousIntent: "product_inquiry" }});
// Training workflowconst trainingResult = await client.triggerTraining(8139, { nodeId: "training-node-uuid", repositoryNodeId: 59, options: { notifyOnComplete: true, webhook: true }});
// Batch processingconst batchResults = await client.executeBatch([ { diagramId: 12345, message: "Query 1" }, { diagramId: 12345, message: "Query 2" }, { diagramId: 12345, message: "Query 3" }], { concurrency: 3, retryFailed: true});Python SDK
Section titled “Python SDK”Installation:
pip install synthreo-sdkQuick Start:
from synthreo import SynthreoClientimport os
client = SynthreoClient( email=os.getenv('SYNTHREO_API_EMAIL'), password=os.getenv('SYNTHREO_API_PASSWORD'), user_id=int(os.getenv('SYNTHREO_USER_ID')), environment='production')
response = client.execute_diagram(12345, "Hello AI!")print(response.get_ai_response())
job_result = client.execute_as_job(12345, "Process this data")print(job_result.get_output())Advanced Features:
from synthreo import SynthreoClient, SynthreoConfigfrom synthreo.webhooks import WebhookHandler
config = SynthreoConfig( rate_limiting={ 'requests_per_minute': 60, 'enable_queue': True, 'max_concurrent': 5 }, polling={ 'job_interval': 30, # 30 seconds 'training_interval': 60, # 60 seconds 'timeout': 3600 # 1 hour }, retry={ 'max_attempts': 3, 'base_delay': 1.0, 'exponential_backoff': True }, webhooks={ 'enabled': True, 'secret': os.getenv('WEBHOOK_SECRET'), 'fallback_to_polling': True })
client = SynthreoClient( email=os.getenv('SYNTHREO_API_EMAIL'), password=os.getenv('SYNTHREO_API_PASSWORD'), user_id=int(os.getenv('SYNTHREO_USER_ID')), config=config)
result = client.execute_diagram(12345, { 'message': 'Follow up question', 'context': { 'conversation_id': 'conv-123', 'user_id': 'user-456', 'session_data': {'preference': 'detailed'} }})
training_result = client.trigger_training(8139, { 'node_id': 'training-node-uuid', 'repository_node_id': 59, 'monitor_progress': True, 'callback': lambda progress: print(f"Training progress: {progress['state']}")})
batch_results = client.execute_batch([ {'diagram_id': 12345, 'message': 'Query 1'}, {'diagram_id': 12345, 'message': 'Query 2'}, {'diagram_id': 12345, 'message': 'Query 3'}], progress_callback=lambda done, total: print(f"Progress: {done}/{total}"))Java SDK
Section titled “Java SDK”Installation (Maven):
<dependency> <groupId>com.synthreo</groupId> <artifactId>synthreo-sdk</artifactId> <version>1.0.0</version></dependency>Installation (Gradle):
implementation 'com.synthreo:synthreo-sdk:1.0.0'Quick Start:
import com.synthreo.SynthreoClient;import com.synthreo.models.ExecutionResult;
SynthreoClient client = SynthreoClient.builder() .email(System.getenv("SYNTHREO_API_EMAIL")) .password(System.getenv("SYNTHREO_API_PASSWORD")) .userId(Integer.parseInt(System.getenv("SYNTHREO_USER_ID"))) .environment(Environment.PRODUCTION) .build();
// Simple executionExecutionResult response = client.executeDiagram(12345, "Hello AI!");System.out.println(response.getAIResponse());
// Async jobJobResult jobResult = client.executeAsJob(12345, "Process this data");System.out.println(jobResult.getOutput());Advanced Features:
import com.synthreo.*;import com.synthreo.config.*;import com.synthreo.webhooks.*;import java.util.concurrent.CompletableFuture;
// Advanced configurationSynthreoConfig config = SynthreoConfig.builder() .rateLimiting(RateLimitConfig.builder() .requestsPerMinute(60) .enableQueue(true) .maxConcurrent(5) .build()) .polling(PollingConfig.builder() .jobInterval(Duration.ofSeconds(30)) .trainingInterval(Duration.ofSeconds(60)) .timeout(Duration.ofHours(1)) .build()) .webhooks(WebhookConfig.builder() .enabled(true) .secret(System.getenv("WEBHOOK_SECRET")) .fallbackToPolling(true) .build()) .build();
SynthreoClient client = SynthreoClient.builder() .email(System.getenv("SYNTHREO_API_EMAIL")) .password(System.getenv("SYNTHREO_API_PASSWORD")) .userId(Integer.parseInt(System.getenv("SYNTHREO_USER_ID"))) .config(config) .build();
// Async execution with CompletableFutureCompletableFuture<ExecutionResult> future = client.executeDiagramAsync(12345, ExecutionRequest.builder() .message("Hello AI!") .context(Map.of( "conversationId", "conv-123", "userId", "user-456" )) .build());
future.thenAccept(result -> { System.out.println("AI Response: " + result.getAIResponse());});
// Training with callbackTrainingResult trainingResult = client.triggerTraining(8139, TrainingRequest.builder() .nodeId("training-node-uuid") .repositoryNodeId(59) .progressCallback(progress -> System.out.println("Training: " + progress.getState())) .build());
// Batch processingList<BatchRequest> requests = Arrays.asList( BatchRequest.of(12345, "Query 1"), BatchRequest.of(12345, "Query 2"), BatchRequest.of(12345, "Query 3"));
List<ExecutionResult> results = client.executeBatch(requests, BatchOptions.builder() .concurrency(3) .retryFailed(true) .progressCallback((done, total) -> System.out.println(String.format("Progress: %d/%d", done, total))) .build());C# SDK
Section titled “C# SDK”Installation (NuGet):
dotnet add package Synthreo.SDKQuick Start:
using Synthreo;
var client = new SynthreoClient(new SynthreoOptions{ Email = Environment.GetEnvironmentVariable("SYNTHREO_API_EMAIL"), Password = Environment.GetEnvironmentVariable("SYNTHREO_API_PASSWORD"), UserId = int.Parse(Environment.GetEnvironmentVariable("SYNTHREO_USER_ID")), Environment = SynthreoEnvironment.Production});
// Simple executionvar response = await client.ExecuteDiagramAsync(12345, "Hello AI!");Console.WriteLine(response.GetAIResponse());
// Async jobvar jobResult = await client.ExecuteAsJobAsync(12345, "Process this data");Console.WriteLine(jobResult.GetOutput());Advanced Features:
using Synthreo;using Synthreo.Configuration;using Synthreo.Webhooks;
var config = new SynthreoConfiguration{ RateLimiting = new RateLimitConfiguration { RequestsPerMinute = 60, EnableQueue = true, MaxConcurrent = 5 }, Polling = new PollingConfiguration { JobInterval = TimeSpan.FromSeconds(30), TrainingInterval = TimeSpan.FromSeconds(60), Timeout = TimeSpan.FromHours(1) }, Webhooks = new WebhookConfiguration { Enabled = true, Secret = Environment.GetEnvironmentVariable("WEBHOOK_SECRET"), FallbackToPolling = true }};
var client = new SynthreoClient(new SynthreoOptions{ Email = Environment.GetEnvironmentVariable("SYNTHREO_API_EMAIL"), Password = Environment.GetEnvironmentVariable("SYNTHREO_API_PASSWORD"), UserId = int.Parse(Environment.GetEnvironmentVariable("SYNTHREO_USER_ID")), Configuration = config});
// Context-aware executionvar result = await client.ExecuteDiagramAsync(12345, new ExecutionRequest{ Message = "Follow up question", Context = new Dictionary<string, object> { ["conversationId"] = "conv-123", ["userId"] = "user-456", ["preferences"] = new { language = "en", detailed = true } }});
// Training with progress monitoringvar trainingResult = await client.TriggerTrainingAsync(8139, new TrainingRequest{ NodeId = "training-node-uuid", RepositoryNodeId = 59, ProgressCallback = progress => Console.WriteLine($"Training: {progress.State}")});
// Batch processingvar requests = new[]{ new BatchRequest(12345, "Query 1"), new BatchRequest(12345, "Query 2"), new BatchRequest(12345, "Query 3")};
var results = await client.ExecuteBatchAsync(requests, new BatchOptions{ Concurrency = 3, RetryFailed = true, ProgressCallback = (done, total) => Console.WriteLine($"Progress: {done}/{total}")});SDK Features
Section titled “SDK Features”Automatic Token Management
Section titled “Automatic Token Management”All SDKs handle JWT token lifecycle automatically:
// Token is automatically refreshed before expirationconst client = new SynthreoClient(credentials);
// No manual token management neededconst result1 = await client.executeDiagram(12345, "Message 1");// ... 23 hours later ...const result2 = await client.executeDiagram(12345, "Message 2"); // Auto-refreshes tokenIntelligent Polling vs Webhooks
Section titled “Intelligent Polling vs Webhooks”SDKs automatically choose the best approach:
client = SynthreoClient(credentials, config={ 'webhooks': { 'enabled': True, 'fallback_to_polling': True, 'timeout': 300 # 5 minutes webhook timeout }})
job_result = client.execute_as_job(12345, "Long running task")Built-in Error Handling
Section titled “Built-in Error Handling”SDKs implement comprehensive error handling:
try { ExecutionResult result = client.executeDiagram(12345, "Hello AI!"); System.out.println(result.getAIResponse());
} catch (AuthenticationException e) { // Automatic token refresh attempted logger.error("Authentication failed: " + e.getMessage());
} catch (RateLimitException e) { // Automatic retry with exponential backoff logger.warn("Rate limited, retrying: " + e.getRetryAfter());
} catch (DiagramExecutionException e) { // Cognitive diagram internal errors logger.error("Execution failed: " + e.getErrorData());
} catch (SynthreoException e) { // General API errors logger.error("API error: " + e.getMessage());}Response Parsing
Section titled “Response Parsing”SDKs automatically parse complex responses:
var result = await client.ExecuteDiagramAsync(12345, "Analyze this data");
// Automatic parsing of outputData JSONstring aiResponse = result.GetAIResponse();var structuredData = result.GetStructuredOutput<MyDataModel>();
// Error information parsed automaticallyif (result.HasErrors){ foreach (var error in result.GetErrors()) { Console.WriteLine($"Error in {error.NodeName}: {error.Message}"); }}
// Metadata and debug informationvar executionMetadata = result.GetMetadata();var debugInfo = result.GetDebugInfo();Webhook Integration
Section titled “Webhook Integration”Express.js Integration
Section titled “Express.js Integration”const express = require('express');const { SynthreoClient, WebhookHandler } = require('@synthreo/sdk');
const app = express();const client = new SynthreoClient(credentials);const webhookHandler = new WebhookHandler({ secret: process.env.WEBHOOK_SECRET, client: client // Links webhooks to client for automatic job resolution});
// Automatic webhook processingapp.use('/webhooks/synthreo', webhookHandler.middleware());
// Custom event handlerswebhookHandler.on('job.completed', async (data, event) => { console.log(`Job ${data.job.id} completed`); // Custom business logic await notifyUser(data.job.id, 'Task completed!');});
webhookHandler.on('training.completed', async (data, event) => { console.log(`Training completed for agent ${data.agent.id}`); // Enable agent for production await enableAgentInProduction(data.agent.id);});
app.listen(3000);Django Integration
Section titled “Django Integration”from django.http import HttpResponsefrom django.views.decorators.csrf import csrf_exemptfrom synthreo import SynthreoClient, WebhookHandler
client = SynthreoClient(credentials)webhook_handler = WebhookHandler( secret=os.getenv('WEBHOOK_SECRET'), client=client)
@csrf_exemptdef synthreo_webhook(request): if request.method == 'POST': # Automatic signature verification and processing result = webhook_handler.process_request( body=request.body, headers=request.META ) return HttpResponse('OK', status=200) return HttpResponse('Method not allowed', status=405)
@webhook_handler.on('job.completed')def handle_job_completion(data, event): print(f"Job {data['job']['id']} completed") # Custom business logic notify_user(data['job']['id'], 'Task completed!')
@webhook_handler.on('training.completed')def handle_training_completion(data, event): print(f"Training completed for agent {data['agent']['id']}") # Enable agent for production enable_agent_in_production(data['agent']['id'])Spring Boot Integration
Section titled “Spring Boot Integration”@RestController@RequestMapping("/webhooks")public class SynthreoWebhookController {
@Autowired private SynthreoClient client;
@Autowired private WebhookHandler webhookHandler;
@PostMapping("/synthreo") public ResponseEntity<String> handleWebhook( @RequestBody String payload, @RequestHeader Map<String, String> headers) {
try { // Automatic signature verification and processing webhookHandler.processWebhook(payload, headers); return ResponseEntity.ok("OK");
} catch (WebhookVerificationException e) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid signature");
} catch (Exception e) { logger.error("Webhook processing error", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error"); } }}
@Componentpublic class SynthreoEventHandlers {
@EventListener public void handleJobCompletion(JobCompletedEvent event) { System.out.println("Job " + event.getJobId() + " completed"); // Custom business logic notifyUser(event.getJobId(), "Task completed!"); }
@EventListener public void handleTrainingCompletion(TrainingCompletedEvent event) { System.out.println("Training completed for agent " + event.getAgentId()); // Enable agent for production enableAgentInProduction(event.getAgentId()); }}Advanced Usage Patterns
Section titled “Advanced Usage Patterns”Conversation Management
Section titled “Conversation Management”const { ConversationManager } = require('@synthreo/sdk');
const conversationManager = new ConversationManager({ client: client, defaultTTL: 3600000, // 1 hour maxMessages: 10});
// Start new conversationconst conversationId = conversationManager.startConversation('user-123');
// Send messages with automatic contextconst response1 = await conversationManager.sendMessage( conversationId, 12345, "What are your business hours?");
const response2 = await conversationManager.sendMessage( conversationId, 12345, "What about holidays?" // Context from previous messages automatically included);
// Get conversation historyconst history = conversationManager.getHistory(conversationId);Batch Processing with Progress
Section titled “Batch Processing with Progress”from synthreo import BatchProcessorimport asyncio
batch_processor = BatchProcessor(client, max_concurrency=5)
async def process_large_dataset(): # Process 1000 items with progress tracking tasks = [ {'diagram_id': 12345, 'message': f'Process item {i}'} for i in range(1000) ]
results = [] async for result in batch_processor.process_batch( tasks, progress_callback=lambda done, total: print(f"Progress: {done}/{total}") ): results.append(result)
# Process results as they come in if result.is_success(): await save_result(result.get_output()) else: await log_error(result.get_error())
return results
results = asyncio.run(process_large_dataset())Custom Training Workflows
Section titled “Custom Training Workflows”import com.synthreo.training.*;
TrainingWorkflow workflow = TrainingWorkflow.builder() .client(client) .dataPreparationStage(DataPreparationStage.builder() .diagramId(10233) // Training data producer .inputData(Map.of("dataSource", "https://docs.company.com")) .pollInterval(Duration.ofSeconds(30)) .build()) .trainingStage(TrainingStage.builder() .diagramId(8139) // RAG model .nodeId("training-node-uuid") .pollInterval(Duration.ofSeconds(60)) .build()) .validationStage(ValidationStage.builder() .testQueries(Arrays.asList( "What is our return policy?", "How do I track my order?", "What are your business hours?" )) .successThreshold(0.85) // 85% accuracy required .build()) .build();
// Execute complete training pipelineTrainingResult result = workflow.execute();
if (result.isSuccess()) { System.out.println("Training completed successfully!"); System.out.println("Validation score: " + result.getValidationScore());} else { System.out.println("Training failed: " + result.getError());}SDK Configuration
Section titled “SDK Configuration”Environment-Specific Configurations
Section titled “Environment-Specific Configurations”const developmentConfig = { environment: 'development', rateLimiting: { requestsPerMinute: 30, enableQueue: false }, polling: { jobInterval: 5000, // 5 seconds for faster development trainingInterval: 15000 // 15 seconds }, logging: { level: 'debug', verbose: true }};
const productionConfig = { environment: 'production', rateLimiting: { requestsPerMinute: 60, enableQueue: true, maxConcurrent: 10 }, polling: { jobInterval: 30000, // 30 seconds trainingInterval: 60000 // 60 seconds }, logging: { level: 'info', verbose: false }, monitoring: { enabled: true, metricsEndpoint: '/metrics' }};
const client = new SynthreoClient(credentials, process.env.NODE_ENV === 'production' ? productionConfig : developmentConfig);Custom HTTP Configuration
Section titled “Custom HTTP Configuration”import httpxfrom synthreo import SynthreoClient
http_client = httpx.AsyncClient( timeout=httpx.Timeout(30.0, connect=10.0), limits=httpx.Limits(max_keepalive_connections=20, max_connections=100), http2=True)
client = SynthreoClient( email=os.getenv('SYNTHREO_API_EMAIL'), password=os.getenv('SYNTHREO_API_PASSWORD'), user_id=int(os.getenv('SYNTHREO_USER_ID')), http_client=http_client)Testing and Debugging
Section titled “Testing and Debugging”Mock Client for Testing
Section titled “Mock Client for Testing”const { MockSynthreoClient } = require('@synthreo/sdk/testing');
describe('AI Agent Integration', () => { let client;
beforeEach(() => { client = new MockSynthreoClient();
// Configure mock responses client.mockDiagram(12345) .withInput("Hello AI!") .returnsOutput("Hello! How can I help you?");
client.mockJob(12345) .withInput("Process data") .completesAfter(5000) // 5 seconds .returnsOutput("Data processing completed"); });
it('should handle simple AI interactions', async () => { const response = await client.executeDiagram(12345, "Hello AI!"); expect(response.getAIResponse()).toBe("Hello! How can I help you?"); });
it('should handle async jobs', async () => { const jobResult = await client.executeAsJob(12345, "Process data"); expect(jobResult.getOutput()).toBe("Data processing completed"); });});Debug Mode
Section titled “Debug Mode”from synthreo import SynthreoClientimport logging
logging.basicConfig(level=logging.DEBUG)
client = SynthreoClient( credentials, debug=True, # Enables request/response logging config={ 'logging': { 'log_requests': True, 'log_responses': True, 'log_headers': False, # Don't log auth headers 'max_body_length': 1000 # Truncate large payloads } })
result = client.execute_diagram(12345, "Test message")Performance Optimization
Section titled “Performance Optimization”Connection Pooling
Section titled “Connection Pooling”// Configure connection pooling for high-throughput applicationsOkHttpClient httpClient = new OkHttpClient.Builder() .connectionPool(new ConnectionPool(50, 5, TimeUnit.MINUTES)) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build();
SynthreoClient client = SynthreoClient.builder() .credentials(credentials) .httpClient(httpClient) .config(SynthreoConfig.builder() .rateLimiting(RateLimitConfig.builder() .requestsPerMinute(120) // Higher limits for enterprise .maxConcurrent(20) .build()) .build()) .build();Caching Strategies
Section titled “Caching Strategies”var client = new SynthreoClient(credentials, new SynthreoConfiguration{ Caching = new CachingConfiguration { Enabled = true,
// Cache frequently accessed diagram info DiagramInfoTTL = TimeSpan.FromHours(1),
// Cache authentication tokens TokenTTL = TimeSpan.FromHours(23), // Refresh 1 hour before expiry
// Cache short-lived responses ResponseTTL = TimeSpan.FromMinutes(5),
// Custom cache provider CacheProvider = new RedisCacheProvider(connectionString) }});Migration from Raw API
Section titled “Migration from Raw API”Gradual Migration Helper
Section titled “Gradual Migration Helper”const { SynthreoClient, MigrationHelper } = require('@synthreo/sdk');
const migrationHelper = new MigrationHelper({ existingHttpClient: yourExistingHttpClient, // Keep existing setup synthreoClient: new SynthreoClient(credentials) // New SDK client});
// Gradual migration - use SDK for new features, keep existing code workingasync function executeWithMigration(diagramId, message) { if (migrationHelper.shouldUseSdk(diagramId)) { // Use new SDK for better features return migrationHelper.client.executeDiagram(diagramId, message); } else { // Fall back to existing implementation return migrationHelper.executeWithExistingClient(diagramId, message); }}By using the official Synthreo SDKs, you get production-ready implementations of all the patterns and best practices covered in our API documentation, with automatic handling of authentication, rate limiting, error recovery, and webhook processing.
Related pages:
- Authentication - obtaining JWT tokens used by the SDKs
- Cognitive Diagrams API - the endpoints the SDKs wrap
- Webhooks - webhook event handling integrated into the SDKs
- Best Practices - patterns the SDKs implement