API v1
Typed decisions over HTTPS
One contract, one endpoint, improving decisions.
1. Set up your decision
Create a decision, then publish its API contract.
Import examples or review generated teaching cases.
Enable a pilot or make an approved version live.
Create a decision-scoped key for this decision.
Copy its decision ID and API contract version.
Models
Each version pins one model. Feedback works with every model.
| Model | Price plan | Notes |
|---|---|---|
| Jev | v1-2026-09-20 | TypeSafe. Your own key is optional. |
| OpenAI Luna | v1-openai-2026-10-08 | OpenAI Decisions API. Rotor's key only. |
Question types: choice, score, noul.
predicate is accepted and stored as noul.
Authentication
Authorization: Bearer rotor_v1_...
Keys appear once. Store them securely.
2. Request a decision
Use IDs from the decision’s API contract.
curl https://rotor.town/api/v1/programs/$PROGRAM_ID/decisions \
-H "Authorization: Bearer $ROTOR_TOWN_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ticket-4411" \
-d '{
"manifest_version": "manifest_example",
"external_id": "ticket-4411",
"input": { "message": "Refund my duplicate charge" }
}'Illustrative response:
{
"decision_id": "decision_example",
"request_id": "request_example",
"program_id": "program_example",
"manifest_version": "manifest_example",
"pipeline_version": "pipeline_example",
"readiness": "pilot",
"external_id": "ticket-4411",
"answers": {
"refund": {
"type": "noul",
"noul": 0.92
}
},
"routing": {
"refund": "review"
},
"usage": {
"input_tokens": 110,
"output_tokens": 0,
"billed_tokens": 256,
"price_plan": "v1-2026-09-20",
"cost_nano_usd": 10496
}
}Save the returned decision ID for feedback.
Compatible promotions and rollbacks keep this endpoint.
Retries may repeat inference; usage is deduplicated.
3. Send outcomes
Use a separate outcome-scoped key.
Record actual outcomes; missing does not mean false.
curl https://rotor.town/api/v1/programs/$PROGRAM_ID/outcomes/batch \
-H "Authorization: Bearer $ROTOR_TOWN_OUTCOME_KEY" \
-H "Content-Type: application/json" \
-d '{
"manifest_version": "manifest_example",
"items": [{
"external_id": "ticket-4411",
"idempotency_key": "ticket-4411-outcome-1",
"state": "mature",
"source": "outcome",
"occurred_at": 1790000000000,
"labels": { "refund": true }
}]
}'Use actual occurrence times in Unix milliseconds.
Ambiguous external IDs require the returned decision ID.
Retry individual failed outcome items using unchanged idempotency keys.
Capture is off by default.
Captured examples require consent before improvement rounds.
Plans
| Plan | Endpoints | Decisions / month | Improvement runs | Improvement spend / month | Retention days | Price |
|---|---|---|---|---|---|---|
| Build | 1 | 10,000 | 3 | $5 | 30 | Free |
| Team | 5 | 1,000,000 | 25 | $50 | 365 | $99 / month |
| Scale | 25 | 10,000,000 | 150 | $250 | 365 | $499 / month |
| Enterprise | Custom | Custom | Custom | Custom | Custom | Custom |
Build is free. Talk to us about Team and Scale.
Workspace exports start with Team.
Capture retention cannot exceed your plan’s retention days.
Read current usage in Plan & usage.
GET /api/v1/workspaces/{workspace_id}/planBring your own TypeSafe key
Plans include decisions on Rotor's TypeSafe key.
Add your own key in Plan & usage.
Decision owners add, replace, or remove it.
We check each key with one synthetic call.
Stored keys are encrypted. We show only the last four characters.
With your key, every Jev call uses it.
We never fall back to our key.
Each response reports usage.key_source: customer or rotor.
Plan, key and model errors
| Code | Status | Meaning |
|---|---|---|
plan_quota_exceeded | 402 | Monthly decisions used. |
provider_key_required | 402 | Rotor-key decisions used. Add your key. |
improvement_quota_exceeded | 402 | Monthly improvement runs used. |
compile_quota_exceeded | 402 | Monthly improvement spend used. Always enforced. |
endpoint_quota_exceeded | 402 | Plan endpoint limit reached. |
plan_feature_required | 402 | Your plan does not include this feature, such as exports. |
retention_limit_exceeded | 402 | Capture retention is longer than your plan allows. |
provider_key_invalid | 424 | TypeSafe rejected your key. Replace it. |
inference_refused | 422 | The model declined this input. Review it by hand. |
Pilots warn at 80%. Only improvement spend blocks a pilot.