The Chemolytic API exposes every active deployment as two prediction endpoints. Use them to integrate predictions into your LIMS, lab automation, or custom scripts.
API predictions require the allow_api_predict plan feature. Free plans don’t include API access. Upgrade to Pro or higher to enable it.
Endpoints
Both endpoints live under the deployment URL:
| Endpoint | Purpose |
|---|
POST /api/.../deployments/{id}/predict/ | Submit JSON-encoded spectra |
POST /api/.../deployments/{id}/predict/file/ | Upload raw CSV files |
The full URL appears on the Integration tab of the deployment detail page.
Authentication
All requests need an API key in the Authorization header:
Authorization: Api-Key sk_<your-key>
See API keys for how to create one.
JSON endpoint
Use this when you can pre-parse spectra into arrays of numbers (e.g., from your own data pipeline).
Request
POST /api/organizations/{slug}/projects/{id}/deployments/{id}/predict/
Authorization: Api-Key sk_xxxxxxxxxxxx
Content-Type: application/json
{
"spectra": [
{
"sample_name": "sample_001",
"y_values": [0.45, 0.52, 0.48, 0.51, 0.47, ...]
},
{
"sample_name": "sample_002",
"y_values": [0.42, 0.49, 0.46, 0.50, 0.45, ...]
}
]
}
| Field | Type | Required | Notes |
|---|
spectra | array | Yes | List of spectrum objects |
spectra[].sample_name | string | Yes | Identifier returned with the prediction |
spectra[].y_values | array of numbers | Yes | One value per x-axis point. Length must match the model’s input size. |
Response (200 OK)
{
"predictions": [
{ "sample_name": "sample_001", "value": 12.34 },
{ "sample_name": "sample_002", "value": 11.87 }
],
"model": {
"id": 42,
"name": "Brix Predictor",
"version": 3,
"target_property": "brix"
}
}
For classification models, value is the predicted category as a string.
File endpoint
Use this when you have raw files exported by your spectrometer and don’t want to parse them yourself.
Request
POST /api/organizations/{slug}/projects/{id}/deployments/{id}/predict/file/
Authorization: Api-Key sk_xxxxxxxxxxxx
Content-Type: multipart/form-data
Form fields:
| Field | Type | Required | Notes |
|---|
file | file | Yes | One or more CSV files. Repeat the field to send multiple. |
sensor_id | integer | Yes | The sensor that produced these files |
Response
Identical to the JSON endpoint.
Code samples
The Integration tab on the deployment detail page generates ready-to-use snippets. Examples:
Python
import requests
ENDPOINT = "https://api.chemolytic.com/api/organizations/your-org/projects/12/deployments/7/predict/"
API_KEY = "sk_xxxxxxxxxxxx"
response = requests.post(
ENDPOINT,
headers={"Authorization": f"Api-Key {API_KEY}"},
json={
"spectra": [
{"sample_name": "sample_001", "y_values": [0.45, 0.52, 0.48, ...]}
]
},
)
response.raise_for_status()
print(response.json())
JavaScript
const response = await fetch(ENDPOINT, {
method: "POST",
headers: {
"Authorization": `Api-Key ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
spectra: [
{ sample_name: "sample_001", y_values: [0.45, 0.52, 0.48] }
],
}),
});
const data = await response.json();
cURL (JSON)
curl -X POST "$ENDPOINT" \
-H "Authorization: Api-Key $API_KEY" \
-H "Content-Type: application/json" \
-d '{"spectra":[{"sample_name":"sample_001","y_values":[0.45,0.52,0.48]}]}'
cURL (file upload)
curl -X POST "$ENDPOINT/file/" \
-H "Authorization: Api-Key $API_KEY" \
-F "file=@sample_001.csv" \
-F "file=@sample_002.csv" \
-F "sensor_id=14"
Limits
| Limit | Value |
|---|
| Max spectra per request | Capped server-side; exceeding returns 400 Bad Request |
| Per-month quota | max_api_predictions_month (plan-based) |
| Request timeout | 30 seconds |
For very large batches, split your spectra across multiple requests.
Errors
| Code | When it happens |
|---|
400 Bad Request | Missing fields, invalid input, point count mismatch, NaN/Inf values, too many spectra |
403 Forbidden | API key doesn’t belong to this project, or not authorized for this deployment |
429 Too Many Requests | Monthly limit exceeded. Body shows {"limit", "used", "requested", "remaining"} |
504 Gateway Timeout | Prediction took longer than 30 seconds. Reduce batch size and retry. |
500 Internal Server Error | Model prediction error. Contact support@chemolytic.com with the deployment ID. |
Example 400 errors
{ "detail": "Spectrum 'sample_001' has 500 points, expected 512." }
{ "detail": "Spectrum 'sample_001' contains NaN or Inf values." }
{ "detail": "Too many spectra (100). Maximum is 50." }
{ "detail": "Deployment is not active." }
{ "detail": "Model not ready (status=building)." }
Example 429 error
{
"detail": "Monthly prediction limit exceeded.",
"limit": 1000,
"used": 950,
"requested": 60,
"remaining": 0
}
Logging and usage
Every API prediction is:
- Recorded in PredictionLog with the API key, sample count, and timestamp (90-day retention)
- Aggregated daily in PredictionUsage for quick quota lookups (kept permanently)
You can see your aggregated usage on the deployment detail page under API predictions this month.
Tips
Batch predictions: send 10-50 spectra per request rather than one at a time. Fewer round-trips, lower latency, less quota waste.
Cache the endpoint URL and API key in environment variables: don’t hard-code them in your scripts. Treat the API key like a password.
Handle 429 gracefully: check remaining in the response and pause until the quota resets if needed.