MATIH Platform is in active MVP development. Documentation reflects current implementation status.
20. Appendices & Reference
SDK Documentation

SDK Documentation

The MATIH Platform provides official SDKs in three languages -- Python, TypeScript, and Java -- to enable programmatic access to platform services. This section covers installation, authentication, core API methods, and usage examples for each SDK.


SDK Overview

SDKLanguageLocationPrimary Use Cases
Python SDKPython 3.10+sdks/python/Data engineering, ML workflows, AI agent integration, Jupyter notebooks
TypeScript SDKTypeScript/Node.js 18+sdks/typescript/Frontend integration, server-side scripting, CI/CD automation
Java Inference SDKJava 17+sdks/inference/Model serving integration, high-performance batch inference, JVM applications

All SDKs share common design principles:

  • Consistent API surface: Method names and parameters are aligned across languages
  • Built-in authentication: JWT token management with automatic refresh
  • Tenant-aware: All operations are scoped to a tenant context
  • Type-safe: Full type definitions for request/response objects
  • Async support: Asynchronous methods for non-blocking operations
  • Error handling: Structured error types that map to the platform error code system
  • Streaming support: Server-Sent Events and WebSocket clients for real-time AI responses

Python SDK

Installation

# Install from PyPI
pip install matih-sdk
 
# Install with optional dependencies for ML workflows
pip install matih-sdk[ml]
 
# Install with all optional dependencies
pip install matih-sdk[all]
 
# Install from source (development)
cd sdks/python
pip install -e ".[dev]"

Requirements

RequirementVersion
Python3.10 or later
httpx0.25+
pydantic2.0+
websockets12.0+ (for streaming)

Authentication

from matih_sdk import MatihClient
 
# Option 1: Username/password authentication
client = MatihClient(
    base_url="https://platform.matih.ai",
    tenant_slug="acme"
)
client.authenticate(email="user@acme.com", password="********")
 
# Option 2: API token authentication (for CI/CD and service accounts)
client = MatihClient(
    base_url="https://platform.matih.ai",
    tenant_slug="acme",
    api_token="mtk_a1b2c3d4e5f6g7h8i9j0..."
)
 
# Option 3: OAuth2 token (from external identity provider)
client = MatihClient(
    base_url="https://platform.matih.ai",
    tenant_slug="acme",
    access_token="eyJhbGciOiJSUzI1NiIs..."
)

The client automatically handles token refresh. When the access token expires, the SDK uses the refresh token to obtain a new access token without interrupting the caller.

Configuration Options

from matih_sdk import MatihClient, ClientConfig
 
config = ClientConfig(
    timeout=60,              # Request timeout in seconds
    max_retries=3,           # Maximum retry attempts for failed requests
    retry_delay=1.0,         # Base delay between retries in seconds
    retry_backoff=2.0,       # Exponential backoff multiplier
    verify_ssl=True,         # Verify TLS certificates
    log_level="INFO",        # SDK logging level
    user_agent="my-app/1.0", # Custom User-Agent header
)
 
client = MatihClient(
    base_url="https://platform.matih.ai",
    tenant_slug="acme",
    config=config
)

AI Service - Conversational Analytics

# Synchronous chat
response = client.ai.chat(
    message="Show me total revenue by region for Q4 2025",
    conversation_id="conv-abc123",  # Optional: continue existing conversation
    data_source="sales_warehouse",
    dialect="trino"
)
 
print(response.text)           # Natural language response
print(response.sql)            # Generated SQL
print(response.data.columns)   # Column names
print(response.data.rows)      # Result rows
print(response.visualization)  # Visualization config
 
# Streaming chat (Server-Sent Events)
async for event in client.ai.chat_stream(
    message="Analyze customer churn trends over the past year",
    data_source="analytics_db"
):
    if event.type == "text":
        print(event.data, end="", flush=True)
    elif event.type == "sql":
        print(f"\nSQL: {event.data}")
    elif event.type == "data":
        print(f"\nResults: {event.data}")
    elif event.type == "visualization":
        print(f"\nChart: {event.data}")
    elif event.type == "agent_step":
        print(f"\n[Agent: {event.data.agent_name}] {event.data.status}")
 
# WebSocket chat (bidirectional real-time)
async with client.ai.ws_connect() as ws:
    await ws.send_message("What are the top 10 products by revenue?")
 
    async for event in ws.events():
        if event.type == "complete":
            print(event.response.text)
            break
        elif event.type == "token":
            print(event.data, end="", flush=True)

AI Service - Text-to-SQL

# Generate SQL from natural language
result = client.ai.text_to_sql(
    question="How many active users signed up last month?",
    dialect="trino",
    catalog="iceberg",
    schema="analytics"
)
 
print(result.sql)          # Generated SQL query
print(result.explanation)  # Natural language explanation of the SQL
print(result.confidence)   # Confidence score (0-1)
print(result.tables_used)  # List of tables referenced
 
# Validate generated SQL
validation = client.ai.validate_sql(
    sql=result.sql,
    dialect="trino"
)
 
print(validation.valid)        # Boolean
print(validation.errors)       # List of validation errors (if any)
print(validation.warnings)     # List of optimization suggestions
 
# Explain existing SQL in natural language
explanation = client.ai.explain_sql(
    sql="SELECT region, SUM(amount) FROM orders GROUP BY region HAVING SUM(amount) > 100000"
)
 
print(explanation.text)  # Human-readable explanation

AI Service - Feedback

# Submit feedback on a response
client.ai.submit_feedback(
    message_id="msg-def456",
    rating="positive",  # "positive", "negative", "neutral"
    comment="SQL was correct and the visualization was helpful",
    correction=None     # Optional: corrected SQL for negative feedback
)
 
# Submit feedback with SQL correction
client.ai.submit_feedback(
    message_id="msg-ghi789",
    rating="negative",
    comment="Revenue should use net_amount, not gross_amount",
    correction="SELECT region, SUM(net_amount) AS total_revenue FROM sales.orders GROUP BY region"
)

Query Engine

# Execute a SQL query
result = client.query.execute(
    sql="SELECT region, COUNT(*) as user_count FROM users GROUP BY region",
    catalog="iceberg",
    schema="analytics",
    timeout=120  # Query timeout in seconds
)
 
print(result.columns)      # ['region', 'user_count']
print(result.rows)         # [['North America', 1250], ['Europe', 890], ...]
print(result.row_count)    # Total number of rows
print(result.duration_ms)  # Execution time in milliseconds
 
# Async query for long-running operations
job = client.query.execute_async(
    sql="SELECT * FROM large_table WHERE date > '2025-01-01'",
    catalog="iceberg",
    schema="warehouse"
)
 
print(job.job_id)   # Job identifier
print(job.status)   # QUEUED, RUNNING, COMPLETED, FAILED
 
# Poll for completion
result = client.query.wait_for_result(job.job_id, timeout=300)
 
# Or check status manually
status = client.query.get_job_status(job.job_id)
if status.status == "COMPLETED":
    result = client.query.get_job_results(job.job_id)

Catalog Service

# Browse catalog
databases = client.catalog.list_databases()
tables = client.catalog.list_tables(database="analytics")
table_meta = client.catalog.get_table("analytics", "orders")
 
print(table_meta.name)
print(table_meta.columns)     # List of column definitions
print(table_meta.row_count)
print(table_meta.size_bytes)
print(table_meta.tags)
 
# Get data lineage
lineage = client.catalog.get_lineage(
    table_id=table_meta.id,
    direction="both",  # "upstream", "downstream", "both"
    depth=3
)
 
# Search metadata
results = client.catalog.search(
    query="customer revenue",
    entity_types=["table", "column"],
    limit=20
)

ML Service

# List models
models = client.ml.list_models()
 
# Register a model
model = client.ml.register_model(
    name="churn_predictor",
    description="Customer churn prediction model",
    tags={"team": "ml-engineering", "use_case": "retention"}
)
 
# Submit a training job
job = client.ml.submit_training_job(
    experiment_name="churn-experiment-v2",
    model_name="churn_predictor",
    config={
        "framework": "pytorch",
        "epochs": 100,
        "batch_size": 64,
        "learning_rate": 0.001,
        "dataset": "s3://matih-data/training/churn_dataset.parquet"
    },
    resources={
        "cpu": "4",
        "memory": "16Gi",
        "gpu": "1"
    }
)
 
# Wait for training completion
result = client.ml.wait_for_training(job.job_id, timeout=3600)
print(result.metrics)  # {'accuracy': 0.94, 'f1_score': 0.91, 'auc': 0.96}
 
# Deploy model for serving
deployment = client.ml.deploy_model(
    model_name="churn_predictor",
    version="3",
    min_replicas=2,
    max_replicas=10,
    target_cpu_utilization=70
)
 
# Run inference
prediction = client.ml.predict(
    deployment_id=deployment.id,
    input_data={
        "customer_age": 35,
        "tenure_months": 24,
        "monthly_spend": 150.0,
        "support_tickets": 3
    }
)
 
print(prediction.output)       # {'churn_probability': 0.23, 'prediction': 'retain'}
print(prediction.latency_ms)   # Inference latency

Dashboard and BI Service

# List dashboards
dashboards = client.bi.list_dashboards()
 
# Create a dashboard
dashboard = client.bi.create_dashboard(
    name="Revenue Overview Q4 2025",
    description="Executive revenue dashboard",
    layout="grid",
    widgets=[
        {
            "type": "kpi",
            "title": "Total Revenue",
            "query": "SELECT SUM(amount) FROM orders WHERE quarter = 'Q4'",
            "position": {"x": 0, "y": 0, "w": 4, "h": 2}
        },
        {
            "type": "bar",
            "title": "Revenue by Region",
            "query": "SELECT region, SUM(amount) FROM orders GROUP BY region",
            "position": {"x": 4, "y": 0, "w": 8, "h": 4}
        }
    ]
)
 
# Export dashboard
pdf_bytes = client.bi.export_dashboard(
    dashboard_id=dashboard.id,
    format="pdf",
    include_filters=True
)
 
with open("revenue_q4.pdf", "wb") as f:
    f.write(pdf_bytes)

Error Handling

from matih_sdk.exceptions import (
    MatihAuthenticationError,
    MatihPermissionError,
    MatihNotFoundError,
    MatihValidationError,
    MatihRateLimitError,
    MatihServerError,
    MatihTimeoutError,
    MatihConnectionError
)
 
try:
    response = client.ai.chat(message="Show me revenue data")
except MatihAuthenticationError as e:
    print(f"Auth failed: {e.code} - {e.message}")
    # Re-authenticate or redirect to login
except MatihPermissionError as e:
    print(f"Access denied: {e.message}")
except MatihRateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except MatihValidationError as e:
    print(f"Validation error: {e.message}")
    for field_error in e.field_errors:
        print(f"  {field_error.field}: {field_error.message}")
except MatihServerError as e:
    print(f"Server error: {e.code} - {e.message}")
    print(f"Request ID: {e.request_id}")
    print(f"Trace ID: {e.trace_id}")
except MatihTimeoutError as e:
    print(f"Request timed out after {e.timeout}s")
except MatihConnectionError as e:
    print(f"Connection failed: {e.message}")

TypeScript SDK

Installation

# Install from npm
npm install @matih/sdk
 
# Install with peer dependencies
npm install @matih/sdk @matih/types
 
# Install from source (development)
cd sdks/typescript
npm install
npm run build

Requirements

RequirementVersion
Node.js18.0 or later
TypeScript5.0+ (if using TypeScript)

Authentication

import { MatihClient, AuthMethod } from '@matih/sdk';
 
// Option 1: Username/password
const client = new MatihClient({
  baseUrl: 'https://platform.matih.ai',
  tenantSlug: 'acme',
});
await client.authenticate({
  email: 'user@acme.com',
  password: '********',
});
 
// Option 2: API token
const client = new MatihClient({
  baseUrl: 'https://platform.matih.ai',
  tenantSlug: 'acme',
  apiToken: 'mtk_a1b2c3d4e5f6g7h8i9j0...',
});
 
// Option 3: Access token (from OAuth2 flow in browser)
const client = new MatihClient({
  baseUrl: 'https://platform.matih.ai',
  tenantSlug: 'acme',
  accessToken: 'eyJhbGciOiJSUzI1NiIs...',
  refreshToken: 'eyJhbGciOiJSUzI1NiIs...',
});

Configuration

const client = new MatihClient({
  baseUrl: 'https://platform.matih.ai',
  tenantSlug: 'acme',
  apiToken: 'mtk_...',
  config: {
    timeout: 60000,          // Request timeout in ms
    maxRetries: 3,           // Maximum retry attempts
    retryDelay: 1000,        // Base retry delay in ms
    retryBackoff: 2,         // Exponential backoff multiplier
    headers: {               // Custom headers
      'X-Custom-Header': 'value',
    },
  },
});

AI Service - Chat

// Synchronous chat
const response = await client.ai.chat({
  message: 'Show me total revenue by region for Q4 2025',
  conversationId: 'conv-abc123',
  dataSource: 'sales_warehouse',
  dialect: 'trino',
});
 
console.log(response.text);
console.log(response.sql);
console.log(response.data?.columns);
console.log(response.data?.rows);
 
// Streaming chat (SSE)
const stream = client.ai.chatStream({
  message: 'Analyze customer churn trends',
  dataSource: 'analytics_db',
});
 
for await (const event of stream) {
  switch (event.type) {
    case 'text':
      process.stdout.write(event.data);
      break;
    case 'sql':
      console.log(`\nGenerated SQL: ${event.data}`);
      break;
    case 'data':
      console.log(`\nResults: ${JSON.stringify(event.data)}`);
      break;
    case 'error':
      console.error(`Error: ${event.data.message}`);
      break;
  }
}
 
// WebSocket chat (React hook example)
import { useMatihChat } from '@matih/sdk/react';
 
function ChatComponent() {
  const { sendMessage, messages, isConnected, isLoading } = useMatihChat({
    client,
    conversationId: 'conv-abc123',
  });
 
  const handleSend = async (text: string) => {
    await sendMessage({ message: text });
  };
 
  return (
    <div>
      {messages.map((msg) => (
        <div key={msg.id}>{msg.text}</div>
      ))}
    </div>
  );
}

Query Engine

// Execute query
const result = await client.query.execute({
  sql: 'SELECT region, COUNT(*) as count FROM users GROUP BY region',
  catalog: 'iceberg',
  schema: 'analytics',
});
 
// Async query
const job = await client.query.executeAsync({
  sql: 'SELECT * FROM large_table WHERE date > \'2025-01-01\'',
});
 
const result = await client.query.waitForResult(job.jobId, {
  timeout: 300000,
  pollInterval: 2000,
});

Error Handling

import {
  MatihAuthenticationError,
  MatihPermissionError,
  MatihNotFoundError,
  MatihRateLimitError,
  MatihServerError,
} from '@matih/sdk';
 
try {
  const response = await client.ai.chat({ message: 'Show revenue' });
} catch (error) {
  if (error instanceof MatihAuthenticationError) {
    console.error(`Auth failed: ${error.code}`);
    // Redirect to login
  } else if (error instanceof MatihRateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter}s`);
    // Retry with delay
  } else if (error instanceof MatihServerError) {
    console.error(`Server error: ${error.code} - ${error.message}`);
    console.error(`Request ID: ${error.requestId}`);
  }
}

Java Inference SDK

Installation

Maven:

<dependency>
  <groupId>ai.matih</groupId>
  <artifactId>matih-inference-sdk</artifactId>
  <version>1.0.0</version>
</dependency>

Gradle:

implementation 'ai.matih:matih-inference-sdk:1.0.0'

Requirements

RequirementVersion
Java17 or later
Jackson2.15+ (transitive dependency)
OkHttp4.12+ (transitive dependency)

Authentication

import ai.matih.sdk.MatihClient;
import ai.matih.sdk.auth.ApiTokenAuth;
import ai.matih.sdk.auth.JwtAuth;
 
// API token authentication
MatihClient client = MatihClient.builder()
    .baseUrl("https://platform.matih.ai")
    .tenantSlug("acme")
    .auth(new ApiTokenAuth("mtk_a1b2c3d4e5f6g7h8i9j0..."))
    .build();
 
// JWT authentication
MatihClient client = MatihClient.builder()
    .baseUrl("https://platform.matih.ai")
    .tenantSlug("acme")
    .auth(new JwtAuth("user@acme.com", "********"))
    .build();

Model Inference

import ai.matih.sdk.inference.*;
 
// Single prediction
PredictionRequest request = PredictionRequest.builder()
    .deploymentId("dep-abc123")
    .input(Map.of(
        "customer_age", 35,
        "tenure_months", 24,
        "monthly_spend", 150.0,
        "support_tickets", 3
    ))
    .build();
 
PredictionResponse response = client.inference().predict(request);
System.out.println("Prediction: " + response.getOutput());
System.out.println("Latency: " + response.getLatencyMs() + "ms");
 
// Batch prediction
BatchPredictionRequest batchRequest = BatchPredictionRequest.builder()
    .deploymentId("dep-abc123")
    .inputs(List.of(
        Map.of("customer_age", 35, "tenure_months", 24),
        Map.of("customer_age", 45, "tenure_months", 12),
        Map.of("customer_age", 28, "tenure_months", 36)
    ))
    .build();
 
BatchPredictionResponse batchResponse = client.inference().predictBatch(batchRequest);
for (PredictionResult result : batchResponse.getResults()) {
    System.out.println(result.getOutput());
}

Query Execution

import ai.matih.sdk.query.*;
 
QueryResult result = client.query().execute(
    QueryRequest.builder()
        .sql("SELECT region, SUM(revenue) FROM sales GROUP BY region")
        .catalog("iceberg")
        .schema("analytics")
        .timeout(Duration.ofSeconds(120))
        .build()
);
 
System.out.println("Columns: " + result.getColumns());
for (List<Object> row : result.getRows()) {
    System.out.println(row);
}

Error Handling

import ai.matih.sdk.exceptions.*;
 
try {
    PredictionResponse response = client.inference().predict(request);
} catch (MatihAuthenticationException e) {
    System.err.println("Authentication failed: " + e.getCode());
} catch (MatihRateLimitException e) {
    System.err.println("Rate limited. Retry after " + e.getRetryAfter() + "s");
    Thread.sleep(e.getRetryAfter() * 1000L);
} catch (MatihServerException e) {
    System.err.println("Server error: " + e.getCode() + " - " + e.getMessage());
    System.err.println("Request ID: " + e.getRequestId());
} catch (MatihException e) {
    System.err.println("SDK error: " + e.getMessage());
}

SDK Comparison Matrix

FeaturePython SDKTypeScript SDKJava Inference SDK
Chat (synchronous)YesYesNo
Chat (streaming SSE)YesYesNo
Chat (WebSocket)YesYesNo
Text-to-SQLYesYesNo
Query executionYesYesYes
Async queriesYesYesYes
Catalog browsingYesYesNo
ML model managementYesYesNo
Model inferenceYesYesYes
Batch inferenceYesYesYes
Dashboard managementYesYesNo
Feedback submissionYesYesNo
React hooksNoYesNo
Auto token refreshYesYesYes
Retry with backoffYesYesYes
Structured errorsYesYesYes
OpenTelemetry tracingYesYesYes