Skip to main content

Get Custom Model

Retrieve detailed information about a specific custom model, including training status and performance metrics.

Endpoint

GET /api/v3/custom_models/{id}

Authentication

Requires API key with custom_models:read scope.

Authorization: Bearer YOUR_API_KEY

Request

Path Parameters

ParameterTypeRequiredDescription
idintegerYesModel ID

Example Request

GET /api/v3/custom_models/123

Response

Success Response

Status Code: 200 OK

The response varies based on training status:

Status 1: Not Running (No Data)

{
"id": 123,
"model_key": "custom_model_123",
"name": "Medical Cardiology EN",
"description": "Cardiology consultations",
"language": "en",
"base_model": "medical",
"training_status": 1,
"status_message": "Model created. Upload training data to begin.",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z"
}

Status 2: Ready to Run (Data Uploaded)

{
"id": 123,
"model_key": "custom_model_123",
"name": "Medical Cardiology EN",
"description": "Cardiology consultations",
"language": "en",
"base_model": "medical",
"training_status": 2,
"status_message": "Data uploaded. Ready to start training.",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-16T08:00:00Z"
}

Status 3: Running (Training In Progress)

{
"id": 123,
"model_key": "custom_model_123",
"name": "Medical Cardiology EN",
"description": "Cardiology consultations",
"language": "en",
"base_model": "medical",
"training_status": 3,
"status_message": "Training in progress...",
"training_progress": 65,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-16T12:30:00Z",
"started_training_at": "2025-01-16T08:00:00Z"
}

Status 4: Success (Training Completed)

{
"id": 123,
"model_key": "custom_model_123",
"name": "Medical Cardiology EN",
"description": "Cardiology consultations",
"language": "en",
"base_model": "medical",
"training_status": 4,
"status_message": "Training completed successfully",
"training_progress": 100,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-16T15:30:00Z",
"started_training_at": "2025-01-16T08:00:00Z",
"finished_training_at": "2025-01-16T15:30:00Z",
"training_metrics": {
"word_error_rate": 12.5,
"character_error_rate": 8.3,
"accuracy_improvement": 18.7,
"training_hours": 7.5,
"test_word_error_rate": 11.2
}
}

Status 5: Failed (Training Error)

{
"id": 123,
"model_key": "custom_model_123",
"name": "Medical Cardiology EN",
"description": "Cardiology consultations",
"language": "en",
"base_model": "medical",
"training_status": 5,
"status_message": "Training failed: Insufficient training data",
"error": "Insufficient training data (minimum 5 hours required, found 2.3 hours)",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-16T10:15:00Z",
"started_training_at": "2025-01-16T08:00:00Z",
"failed_at": "2025-01-16T10:15:00Z"
}

Examples

cURL

curl https://api.scriptix.io/api/v3/custom_models/123 \
-H "Authorization: Bearer YOUR_API_KEY"

Python - Poll Training Progress

import requests
import time

def wait_for_training(model_id, poll_interval=30):
"""Poll model status until training completes or fails."""
url = f"https://api.scriptix.io/api/v3/custom_models/{model_id}"
headers = {"Authorization": "Bearer YOUR_API_KEY"}

print(f"Monitoring training for model {model_id}...")

while True:
response = requests.get(url, headers=headers)
model = response.json()

status = model['training_status']
message = model['status_message']

if status == 3: # Running
progress = model.get('training_progress', 0)
print(f"Training: {progress}% - {message}")
elif status == 4: # Success
metrics = model['training_metrics']
print(f"✓ Training completed!")
print(f" WER: {metrics['word_error_rate']}%")
print(f" Improvement: {metrics['accuracy_improvement']}%")
return model
elif status == 5: # Failed
print(f"✗ Training failed: {model['error']}")
return model
else:
print(f"Status: {message}")

time.sleep(poll_interval)

# Usage
model = wait_for_training(123, poll_interval=60)

JavaScript - Monitor Training

const axios = require('axios');

async function monitorTraining(modelId, pollInterval = 30000) {
const url = `https://api.scriptix.io/api/v3/custom_models/${modelId}`;
const headers = { 'Authorization': 'Bearer YOUR_API_KEY' };

console.log(`Monitoring training for model ${modelId}...`);

while (true) {
const { data: model } = await axios.get(url, { headers });

const status = model.training_status;

if (status === 3) {
console.log(`Training: ${model.training_progress}%`);
} else if (status === 4) {
console.log('✓ Training completed!');
console.log(`WER: ${model.training_metrics.word_error_rate}%`);
return model;
} else if (status === 5) {
console.log(`✗ Training failed: ${model.error}`);
return model;
}

await new Promise(resolve => setTimeout(resolve, pollInterval));
}
}

// Usage
monitorTraining(123, 60000);

TypeScript

interface CustomModel {
id: number;
model_key: string;
name: string;
description: string | null;
language: string;
base_model: string;
training_status: 1 | 2 | 3 | 4 | 5;
status_message: string;
training_progress?: number;
error?: string;
created_at: string;
updated_at: string;
started_training_at?: string;
finished_training_at?: string;
failed_at?: string;
training_metrics?: {
word_error_rate: number;
character_error_rate?: number;
accuracy_improvement: number;
training_hours?: number;
};
}

const getModel = async (modelId: number): Promise<CustomModel> => {
const response = await fetch(
`https://api.scriptix.io/api/v3/custom_models/${modelId}`,
{
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}
);

if (!response.ok) {
throw new Error(`Failed to get model: ${response.statusText}`);
}

return response.json();
};

// Usage
const model = await getModel(123);
console.log(`Status: ${model.status_message}`);

Error Responses

404 Not Found

{
"error": "Not Found",
"message": "Model not found",
"error_code": "MODEL_NOT_FOUND"
}

401 Unauthorized

{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}

Use Cases

Check If Model Is Ready

def is_model_ready(model_id):
"""Check if model completed training successfully."""
model = get_model(model_id)
return model['training_status'] == 4

if is_model_ready(123):
print("Model ready for production use!")
else:
print("Model not ready yet")

Get Training Metrics

def get_training_metrics(model_id):
"""Get training performance metrics if available."""
model = get_model(model_id)

if model['training_status'] != 4:
return None

return model.get('training_metrics')

metrics = get_training_metrics(123)
if metrics:
print(f"WER: {metrics['word_error_rate']}%")
print(f"Improvement: {metrics['accuracy_improvement']}%")

Monitor Multiple Models

def get_training_summary(model_ids):
"""Get training status summary for multiple models."""
summary = {
'running': [],
'completed': [],
'failed': [],
'not_started': []
}

for model_id in model_ids:
model = get_model(model_id)
status = model['training_status']

if status == 3:
summary['running'].append(model)
elif status == 4:
summary['completed'].append(model)
elif status == 5:
summary['failed'].append(model)
else:
summary['not_started'].append(model)

return summary

# Check status of all models
models = [123, 124, 125, 126]
summary = get_training_summary(models)

print(f"Running: {len(summary['running'])}")
print(f"Completed: {len(summary['completed'])}")
print(f"Failed: {len(summary['failed'])}")

Polling Best Practices

When monitoring training progress:

  • Poll interval: 30-60 seconds recommended
  • Timeout: Set maximum wait time (e.g., 24 hours)
  • Error handling: Handle network errors and retries
  • Rate limits: Stay within 100 requests/minute
  • Backoff: Increase interval if approaching rate limits
import time
import requests
from datetime import datetime, timedelta

def poll_until_complete(model_id, timeout_hours=24):
"""Poll with timeout and proper error handling."""
start_time = datetime.now()
timeout = timedelta(hours=timeout_hours)
poll_interval = 60 # 1 minute

while datetime.now() - start_time < timeout:
try:
model = get_model(model_id)
status = model['training_status']

if status in [4, 5]: # Completed or failed
return model

# Still running, wait before next poll
time.sleep(poll_interval)

except requests.exceptions.RequestException as e:
print(f"Network error: {e}. Retrying in {poll_interval}s...")
time.sleep(poll_interval)

raise TimeoutError(f"Training did not complete within {timeout_hours} hours")

See Data Models for complete field reference.