POST /v1/platform/evaluations
Creates an evaluation request. The AI model grades the learner's answer and returns structured feedback including score, strengths, and improvement suggestions.
Tiers
The tier field selects the quality and pricing contract for the request.
If omitted, TutorFlow assigns a default based on evaluationType:
| Evaluation Type | Default Tier | Price |
|---|---|---|
exact | fast | $0.01 |
rubric_short_answer | standard | $0.03 |
open_ended | advanced | $0.05 |
TutorFlow stores a price snapshot at request time so billing remains consistent even if pricing is updated later.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
evaluationType | string | Yes | open_ended, rubric_short_answer, or exact |
questionText | string | Yes | The question being evaluated |
learnerAnswer | string | Yes | The student's answer |
tier | string | No | fast, standard, or advanced. Defaults based on evaluationType (see above) |
language | string | No | Language for feedback (default: en). Supports any language the AI model can handle |
maxScore | number | No | Maximum score (default: 10) |
referenceAnswer | string | No | Expected answer (required for exact type) |
rubric | object | No | Rubric criteria object (required for rubric_short_answer type) |
feedbackOptions | object | No | Optional feedback formatting preferences |
idempotencyKey | string | No | Prevents duplicate processing. Can also be sent via Idempotency-Key HTTP header |
mode | string | No | sync (default) or async |
Example Request
curl -X POST https://api.tutorflow.io/v1/platform/evaluations \
-H "Authorization: Bearer tf_platform_..." \
-H "Content-Type: application/json" \
-d '{
"evaluationType": "open_ended",
"tier": "advanced",
"questionText": "Explain the water cycle",
"learnerAnswer": "Water evaporates from oceans...",
"language": "en",
"maxScore": 10
}'Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Evaluation request ID |
status | string | PENDING, PROCESSING, COMPLETED, or FAILED |
evaluationType | string | The evaluation type used |
tier | string | The tier applied |
priceSnapshot | object | Pricing details at time of request |
score | number | Achieved score (null if not yet complete) |
maxScore | number | Maximum possible score |
normalizedScore | number | Score normalized to 0-1 range |
confidence | number | AI confidence in the evaluation (0-1) |
strengths | string[] | Identified strengths in the answer |
mistakes | string[] | Identified mistakes or weaknesses |
suggestions | string[] | Improvement suggestions |
feedbackSummary | string | Overall feedback narrative |
nextStep | string | Recommended next learning step |
rubricBreakdown | object[] | Per-criterion scores (rubric type only) |
isTerminal | boolean | Whether the evaluation is in a final state |
pollAfterMs | number | Suggested polling interval in ms (async mode) |
idempotencyKey | string | The idempotency key if provided |
createdAt | string | ISO 8601 timestamp |
completedAt | string | ISO 8601 timestamp (null if not complete) |
Example Response
{
"id": "2f4ad455-1e8e-4b6c-9f3a-7ebf4cf6f483",
"status": "COMPLETED",
"evaluationType": "open_ended",
"tier": "advanced",
"priceSnapshot": {
"category": "evaluation",
"catalogKey": "evaluation.advanced",
"tier": "advanced",
"amountUsd": 0.05,
"unit": "evaluation",
"currency": "USD",
"source": "platform_pricing_catalog_v1"
},
"score": 8,
"maxScore": 10,
"normalizedScore": 0.8,
"confidence": 0.92,
"strengths": [
"Correctly identifies evaporation as a key process",
"Good use of scientific terminology"
],
"mistakes": [
"Did not mention condensation"
],
"suggestions": [
"Include condensation as a step",
"Mention the role of transpiration from plants"
],
"feedbackSummary": "Strong understanding of the water cycle with clear explanation of evaporation and precipitation.",
"nextStep": "Study the condensation and precipitation phases to complete your understanding.",
"isTerminal": true,
"createdAt": "2026-03-19T10:30:00Z",
"completedAt": "2026-03-19T10:30:01Z"
}Async Mode
Set "mode": "async" to queue the evaluation for background processing. This is useful
for long-running evaluations or when you don't need the result immediately.
curl -X POST https://api.tutorflow.io/v1/platform/evaluations \
-H "Authorization: Bearer tf_platform_..." \
-H "Content-Type: application/json" \
-d '{
"evaluationType": "open_ended",
"questionText": "Write an essay about climate change",
"learnerAnswer": "Climate change is...",
"mode": "async"
}'The response returns immediately with "status": "PENDING" and a pollAfterMs value:
{
"id": "2f4ad455-1e8e-4b6c-9f3a-7ebf4cf6f483",
"status": "PENDING",
"evaluationType": "open_ended",
"isTerminal": false,
"pollAfterMs": 1000
}Use the Get Evaluation endpoint to poll
for results, or configure Webhooks to receive
evaluation.completed or evaluation.failed events.
Idempotency
Pass an idempotencyKey in the request body or Idempotency-Key header to prevent
duplicate evaluations. If the same key is sent again, the original result is returned
without re-processing.
curl -X POST https://api.tutorflow.io/v1/platform/evaluations \
-H "Authorization: Bearer tf_platform_..." \
-H "Idempotency-Key: my-unique-request-123" \
-H "Content-Type: application/json" \
-d '{ ... }'The body field idempotencyKey takes precedence over the header if both are provided.
File Attachments
Use multipart/form-data to include file attachments (max 10 files per field):
curl -X POST https://api.tutorflow.io/v1/platform/evaluations \
-H "Authorization: Bearer tf_platform_..." \
-F "evaluationType=rubric_short_answer" \
-F "tier=standard" \
-F "questionText=Analyze this data set" \
-F "learnerAnswer=Based on the data..." \
-F 'rubric={"criteria":[{"name":"Accuracy","description":"Correct interpretation","maxScore":5}]}' \
-F "rubricFiles=@rubric.pdf" \
-F "answerFiles=@student_work.pdf"See Pricing and Billing for
how tier maps into TutorFlow billing.