API Integration Guide
Make real-time predictions with your adaptive learning loops using our REST API. Loops continuously improve with each prediction and training example.
Overview
Heimdall Loop provides three main API endpoints:
- Create Loop Definition - Define your loop structure
- Train Loop - Provide training data to improve your model
- Predict - Make predictions and get feature contributions
Base URL
All Loop API endpoints are available at:
https://loop.heimdallapp.org
Authentication
All endpoints require authentication via headers:
- X-api-key - Your API key (generated from the loop detail page)
- X-username - Your Heimdall username
- x-loop-id - Your Loop ID (found on the loop detail page)
- Navigate to your loop page in the Heimdall dashboard
- Click "Generate API Key" at the top of the page
- Find your Loop ID on the loop detail page
- Use your Heimdall username for authentication
1. Create Loop Definition
Define your adaptive learning loop structure.
POST /definitions/
Request Body
{
"name": "Customer Recommendation Loop",
"task_type": "classification",
"input_schema": {
"user_id": "string",
"item_id": "string",
"rating": "integer",
"time_of_day": "integer"
},
"output_schema": {
"recommendation": "string"
}
}
Request Fields
- name (string, required) - Descriptive name for your loop
- task_type (string, required) - Either
"classification"or"regression" - input_schema (object, required) - Dictionary mapping field names to types
- Supported types:
string,integer,float,boolean,array,object
- Supported types:
- output_schema (object, required) - Dictionary with exactly one field
- Must contain exactly one field name and type
Response
{
"definition_id": "507f1f77bcf86cd799439011",
"name": "Customer Recommendation Loop",
"task_type": "classification",
"input_schema": {
"user_id": "string",
"item_id": "string",
"rating": "integer",
"time_of_day": "integer"
},
"output_schema": {
"recommendation": "string"
},
"model_url": "s3://bucket/model.pkl",
"created_at": "2024-01-01T00:00:00"
}
2. Train Loop
Provide training data to improve your loop model. You can train with single examples or batches.
POST /train/
Request Headers
- X-api-key - Your API key
- X-username - Your username
- x-loop-id - Your Loop ID
Request Body
Single Training Example:
{
"data": {
"user_id": "user_123",
"item_id": "item_456",
"rating": 5,
"time_of_day": 14,
"recommendation": "highly_recommended"
}
}
Batch Training (Multiple Examples):
{
"data": [
{
"user_id": "user_123",
"item_id": "item_456",
"rating": 5,
"time_of_day": 14,
"recommendation": "highly_recommended"
},
{
"user_id": "user_124",
"item_id": "item_789",
"rating": 2,
"time_of_day": 22,
"recommendation": "not_recommended"
}
]
}
Response
{
"status": "success",
"message": "Successfully trained 2 sample(s)",
"trained_samples": 2,
"failed_samples": 0,
"errors": []
}
3. Make Predictions
Make predictions and get feature contributions for explainability.
POST /predict/
Request Headers
- X-api-key - Your API key
- X-username - Your username
- x-loop-id - Your Loop ID
Request Body
Single Prediction:
{
"data": {
"user_id": "user_123",
"item_id": "item_456",
"rating": 4,
"time_of_day": 15
}
}
Batch Predictions:
{
"data": [
{
"user_id": "user_123",
"item_id": "item_456",
"rating": 4,
"time_of_day": 15
},
{
"user_id": "user_125",
"item_id": "item_999",
"rating": 3,
"time_of_day": 20
}
]
}
Response
{
"status": "success",
"message": "Successfully predicted 2 sample(s)",
"predictions": [
{
"recommendation": "recommended",
"explanation": {
"top_contributors": [
{
"feature": "rating",
"contribution": 0.42,
"weight": 1.2,
"value": 4.0
},
{
"feature": "time_of_day",
"contribution": 0.28,
"weight": 0.8,
"value": 15.0
},
{
"feature": "user_id",
"contribution": 0.15,
"weight": 0.5,
"value": 0.0
}
]
}
},
{
"recommendation": "not_recommended",
"explanation": {
"top_contributors": [
{
"feature": "rating",
"contribution": -0.35,
"weight": 1.2,
"value": 3.0
},
{
"feature": "time_of_day",
"contribution": -0.22,
"weight": 0.8,
"value": 20.0
}
]
}
}
],
"failed_samples": 0,
"errors": []
}
Understanding Feature Contributions
Each prediction includes an explanation object with top_contributors showing:
- feature - The input field name
- contribution - How much this feature contributed to the prediction (positive or negative)
- weight - The model's learned weight for this feature
- value - The actual value of this feature in the input
This helps you understand which factors most impact each prediction.
Complete Python Example
import requests
# Configuration
API_KEY = 'YOUR_API_KEY'
USERNAME = 'YOUR_USERNAME'
LOOP_ID = 'YOUR_LOOP_ID'
BASE_URL = 'https://loop.heimdallapp.org'
headers = {
'X-api-key': API_KEY,
'X-username': USERNAME,
'x-loop-id': LOOP_ID,
'Content-Type': 'application/json'
}
# Make a prediction
prediction_data = {
"data": {
"user_id": "user_123",
"item_id": "item_456",
"rating": 4,
"time_of_day": 15
}
}
response = requests.post(
f'{BASE_URL}/predict/',
headers=headers,
json=prediction_data
)
if response.status_code == 200:
result = response.json()
prediction = result['predictions'][0]
# Get the predicted value
output_field = list(prediction.keys())[0] # Get the output field name
predicted_value = prediction[output_field]
print(f"Prediction: {predicted_value}")
# Get feature contributions
if 'explanation' in prediction:
print("\nTop Contributing Features:")
for contributor in prediction['explanation']['top_contributors']:
print(f" {contributor['feature']}: {contributor['contribution']:+.2f} "
f"(weight: {contributor['weight']:.2f}, value: {contributor['value']})")
else:
print(f"Error: {response.status_code}")
print(response.text)
Continuous Learning Workflow
Here's a complete example showing the continuous learning cycle:
import requests
API_KEY = 'YOUR_API_KEY'
USERNAME = 'YOUR_USERNAME'
LOOP_ID = 'YOUR_LOOP_ID'
BASE_URL = 'https://loop.heimdallapp.org'
headers = {
'X-api-key': API_KEY,
'X-username': USERNAME,
'x-loop-id': LOOP_ID,
'Content-Type': 'application/json'
}
# 1. Make a prediction
prediction_response = requests.post(
f'{BASE_URL}/predict/',
headers=headers,
json={
"data": {
"user_id": "user_123",
"item_id": "item_456",
"rating": 4,
"time_of_day": 15
}
}
)
prediction = prediction_response.json()['predictions'][0]
predicted_recommendation = prediction['recommendation']
# 2. Use the prediction in your application
print(f"Showing recommendation: {predicted_recommendation}")
# 3. When you get user feedback (ground truth), feed it back as training data
# For example, if the user actually clicked/interacted:
actual_outcome = "highly_recommended" # Ground truth from user behavior
training_data = {
"data": {
"user_id": "user_123",
"item_id": "item_456",
"rating": 4,
"time_of_day": 15,
"recommendation": actual_outcome # Include the actual outcome
}
}
# 4. Train the model with the feedback
train_response = requests.post(
f'{BASE_URL}/train/',
headers=headers,
json=training_data
)
print(f"Model updated: {train_response.json()['message']}")
Error Handling
Common Error Codes
- 400 Bad Request - Invalid request format or missing required fields
- 401 Unauthorized - Invalid API key, username, or Loop ID
- 422 Unprocessable Entity - Invalid data types or schema mismatch
- 500 Internal Server Error - Server-side error
Error Response Format
{
"status": "failed",
"message": "Error message describing what went wrong",
"errors": [
"Detailed error message 1",
"Detailed error message 2"
]
}
Best Practices
- Always check response status codes
- Implement retry logic for transient errors (5xx)
- Validate data types match your schema before sending
- Cache API keys securely (never commit to version control)
- Monitor API usage and rate limits
- Handle partial failures in batch requests (check
failed_samples)
Rate Limits
Loops are designed for high-volume usage. Contact support if you need information about specific rate limits for your use case.
Next Steps
- Learn about monitoring your loop performance
- Explore best practices for continuous learning
- See deployment guide for production setup