/api/v1/account/status
Account status and remaining credits
Developer docs
Mark work, check integrity, sync a roster, and pull results back into your LMS or MIS. Every call uses the same key; sandbox keys return mocks and never charge credits.
Base URL https://feedbackflows.org/api/v1 · Header X-API-Key
GET /me to confirm scopes and remaining rate limits.POST /jobs/estimate-cost before you queue work.callback_url.Send X-API-Key on every request. Default scopes are marking, integrity and analytics. Add media or admin when you need them. Sync calls are 60/minute; job submissions are 10/hour. Async POSTs accept an Idempotency-Key header.
curl https://feedbackflows.org/api/v1/me \ -H "X-API-Key: $FEEDBACKFLOWS_API_KEY"
import os, requests
r = requests.get(
"https://feedbackflows.org/api/v1/me",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
)
print(r.json())
Runs against this origin. Use a sandbox key so nothing is billed. The dropdown is built from the live OpenAPI spec.
Quick testers (including the older “v2” URLs) still call /api/v1. Dedicated pages are useful for file uploads and polling.
Generated from the live routing table. Search filters this list.
No endpoints match that search.
/api/v1/account/status
Account status and remaining credits
/api/v1/me
Current API key, scopes and remaining rate limits
/api/v1/openapi.json
This document (no API key required)
/api/v1/stats/users
Total user count (requires an admin-owned key)
/api/v1/test
Validate API key
/api/v1/ai-tutor
Formative tutor feedback on a draft
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
student_draft |
string | yes |
mode |
string | no |
marking_rubric |
string | no |
persona |
string | no |
curl -X POST https://feedbackflows.org/api/v1/ai-tutor \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"student_draft": "example",
"mode": "general",
"marking_rubric": "example",
"persona": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/ai-tutor",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"student_draft": "example",
"mode": "general",
"marking_rubric": "example",
"persona": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/ai-tutor", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"student_draft": "example",
"mode": "general",
"marking_rubric": "example",
"persona": "example"
}),
});
/api/v1/interactive-feedback
Inline feedback against a list of criteria
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
student_text |
string | yes |
marking_criteria |
array | yes |
curl -X POST https://feedbackflows.org/api/v1/interactive-feedback \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"student_text": "example",
"marking_criteria": [
"Clarity"
]
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/interactive-feedback",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"student_text": "example",
"marking_criteria": [
"Clarity"
]
},
)
await fetch("https://feedbackflows.org/api/v1/interactive-feedback", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"student_text": "example",
"marking_criteria": [
"Clarity"
]
}),
});
/api/v1/smart-essay-marker
Mark one essay against criteria (synchronous) (deprecated)
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
essay_text |
string | yes |
marking_criteria |
array | yes |
curl -X POST https://feedbackflows.org/api/v1/smart-essay-marker \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"essay_text": "example",
"marking_criteria": [
"Clarity"
]
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/smart-essay-marker",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"essay_text": "example",
"marking_criteria": [
"Clarity"
]
},
)
await fetch("https://feedbackflows.org/api/v1/smart-essay-marker", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"essay_text": "example",
"marking_criteria": [
"Clarity"
]
}),
});
/api/v1/students/{student_id}/worksheet
Generate a targeted practice worksheet
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
weaknesses_list |
array | no |
format |
string | no |
level |
string | no |
num_questions |
integer | no |
curl -X POST https://feedbackflows.org/api/v1/students/{student_id}/worksheet \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"weaknesses_list": [
"Clarity"
],
"format": "example",
"level": "example",
"num_questions": 1
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/students/{student_id}/worksheet",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"weaknesses_list": [
"Clarity"
],
"format": "example",
"level": "example",
"num_questions": 1
},
)
await fetch("https://feedbackflows.org/api/v1/students/{student_id}/worksheet", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"weaknesses_list": [
"Clarity"
],
"format": "example",
"level": "example",
"num_questions": 1
}),
});
/api/v1/ai-detector
Hybrid AI detector (synchronous, detailed response) (deprecated)
Requires the `integrity` scope.
| Body field | Type | Required |
|---|---|---|
document_text |
string | yes |
academic_mode |
boolean | no |
curl -X POST https://feedbackflows.org/api/v1/ai-detector \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_text": "example",
"academic_mode": false
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/ai-detector",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"document_text": "example",
"academic_mode": false
},
)
await fetch("https://feedbackflows.org/api/v1/ai-detector", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"document_text": "example",
"academic_mode": false
}),
});
/api/v1/full-reference-check
Bibliography and citation checker
Requires the `integrity` scope.
| Body field | Type | Required |
|---|---|---|
document_text |
string | yes |
style |
string | no |
enable_semantic_check |
boolean | no |
curl -X POST https://feedbackflows.org/api/v1/full-reference-check \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_text": "example",
"style": "APA",
"enable_semantic_check": false
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/full-reference-check",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"document_text": "example",
"style": "APA",
"enable_semantic_check": false
},
)
await fetch("https://feedbackflows.org/api/v1/full-reference-check", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"document_text": "example",
"style": "APA",
"enable_semantic_check": false
}),
});
/api/v1/reference-check
Legacy AI detector (simplified response) (deprecated)
Requires the `integrity` scope.
| Body field | Type | Required |
|---|---|---|
document_text |
string | yes |
curl -X POST https://feedbackflows.org/api/v1/reference-check \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_text": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/reference-check",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"document_text": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/reference-check", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"document_text": "example"
}),
});
/api/v1/style-comparison
Compare one submission against a student's writing samples
Requires the `integrity` scope.
| Body field | Type | Required |
|---|---|---|
student_id |
integer | yes |
submission_text |
string | yes |
curl -X POST https://feedbackflows.org/api/v1/style-comparison \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"student_id": 1,
"submission_text": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/style-comparison",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"student_id": 1,
"submission_text": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/style-comparison", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"student_id": 1,
"submission_text": "example"
}),
});
/api/v1/ai-detector/jobs
Queue AI detection (preferred over the synchronous endpoint)
Requires one of the following scopes: `integrity` or `marking`.
| Body field | Type | Required |
|---|---|---|
document_text |
string | yes |
academic_mode |
boolean | no |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/ai-detector/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_text": "example",
"academic_mode": false,
"callback_url": "https://example.com/webhooks/feedbackflows"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/ai-detector/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"document_text": "example",
"academic_mode": false,
"callback_url": "https://example.com/webhooks/feedbackflows"
},
)
await fetch("https://feedbackflows.org/api/v1/ai-detector/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"document_text": "example",
"academic_mode": false,
"callback_url": "https://example.com/webhooks/feedbackflows"
}),
});
/api/v1/ai-detector/jobs/{job_id}
AI detection job status and results
Requires one of the following scopes: `integrity` or `marking`.
/api/v1/ai-detector/jobs/{job_id}/cancel
Cancel an AI detector job and refund unused credits
Requires one of the following scopes: `integrity` or `marking`.
/api/v1/ai-tutor/jobs
Queue AI tutor feedback
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
student_draft |
string | yes |
mode |
string | no |
marking_rubric |
string | no |
persona |
string | no |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/ai-tutor/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"student_draft": "example",
"mode": "example",
"marking_rubric": "example",
"persona": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/ai-tutor/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"student_draft": "example",
"mode": "example",
"marking_rubric": "example",
"persona": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/ai-tutor/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"student_draft": "example",
"mode": "example",
"marking_rubric": "example",
"persona": "example"
}),
});
/api/v1/ai-tutor/jobs/{job_id}
AI tutor job status and result
Requires the `marking` scope.
/api/v1/ai-tutor/jobs/{job_id}/cancel
Cancel an AI tutor job and refund unused credits
Requires the `marking` scope.
/api/v1/automarking/jobs
Queue question-by-question automarking
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
zip_base64 |
string | yes |
question_template_id |
integer | no |
questions |
array | no |
mark_mode |
string | no |
filename |
string | no |
callback_url |
string | no |
credit_check_only |
boolean | no |
curl -X POST https://feedbackflows.org/api/v1/automarking/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"zip_base64": "UEsDBBQAAAAA",
"question_template_id": 1,
"questions": [],
"mark_mode": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/automarking/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"zip_base64": "UEsDBBQAAAAA",
"question_template_id": 1,
"questions": [],
"mark_mode": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/automarking/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"zip_base64": "UEsDBBQAAAAA",
"question_template_id": 1,
"questions": [],
"mark_mode": "example"
}),
});
/api/v1/automarking/jobs/{job_id}
Automarking job status, progress and results
Requires the `marking` scope.
/api/v1/automarking/jobs/{job_id}/cancel
Cancel an automarking or exam-marker job and refund unused credits
Requires the `marking` scope.
/api/v1/batch-style/jobs
Queue a batch style comparison
Requires the `integrity` scope.
| Body field | Type | Required |
|---|---|---|
zip_base64 |
string | yes |
filename |
string | no |
callback_url |
string | no |
credit_check_only |
boolean | no |
curl -X POST https://feedbackflows.org/api/v1/batch-style/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"callback_url": "https://example.com/webhooks/feedbackflows",
"credit_check_only": false
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/batch-style/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"callback_url": "https://example.com/webhooks/feedbackflows",
"credit_check_only": false
},
)
await fetch("https://feedbackflows.org/api/v1/batch-style/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"callback_url": "https://example.com/webhooks/feedbackflows",
"credit_check_only": false
}),
});
/api/v1/batch-style/jobs/{job_id}
Batch style job status and comparisons
Requires the `integrity` scope.
/api/v1/batch-style/jobs/{job_id}/cancel
Cancel a batch style job
Requires the `integrity` scope.
/api/v1/exam-marker/jobs
Queue exam script marking for one student
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
student_id |
integer | yes |
zip_base64 |
string | yes |
filename |
string | no |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/exam-marker/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"student_id": 1,
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"callback_url": "https://example.com/webhooks/feedbackflows"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/exam-marker/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"student_id": 1,
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"callback_url": "https://example.com/webhooks/feedbackflows"
},
)
await fetch("https://feedbackflows.org/api/v1/exam-marker/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"student_id": 1,
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"callback_url": "https://example.com/webhooks/feedbackflows"
}),
});
/api/v1/exam-marker/jobs/{job_id}/cancel
Cancel an automarking or exam-marker job and refund unused credits
Requires the `marking` scope.
/api/v1/interactive-feedback/jobs
Queue interactive feedback
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
student_text |
string | yes |
marking_criteria |
array | yes |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/interactive-feedback/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"student_text": "example",
"marking_criteria": [
"Clarity"
],
"callback_url": "https://example.com/webhooks/feedbackflows"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/interactive-feedback/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"student_text": "example",
"marking_criteria": [
"Clarity"
],
"callback_url": "https://example.com/webhooks/feedbackflows"
},
)
await fetch("https://feedbackflows.org/api/v1/interactive-feedback/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"student_text": "example",
"marking_criteria": [
"Clarity"
],
"callback_url": "https://example.com/webhooks/feedbackflows"
}),
});
/api/v1/interactive-feedback/jobs/{job_id}
Interactive-feedback job status and result
Requires the `marking` scope.
/api/v1/interactive-feedback/jobs/{job_id}/cancel
Cancel an interactive-feedback job and refund unused credits
Requires the `marking` scope.
/api/v1/jobs
List recent jobs for this account, filtered by the key's scopes
/api/v1/jobs/estimate-cost
Estimate the credit cost of an async job
| Body field | Type | Required |
|---|---|---|
job_type |
string | yes |
file_count |
integer | no |
student_count |
integer | no |
curl -X POST https://feedbackflows.org/api/v1/jobs/estimate-cost \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"job_type": "example",
"file_count": 1,
"student_count": 1
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/jobs/estimate-cost",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"job_type": "example",
"file_count": 1,
"student_count": 1
},
)
await fetch("https://feedbackflows.org/api/v1/jobs/estimate-cost", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"job_type": "example",
"file_count": 1,
"student_count": 1
}),
});
/api/v1/learner-packs/jobs
Queue a learner pack build
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
student_id |
integer | yes |
template_id |
integer | no |
selected_result_refs |
array | no |
generation_options |
object | no |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/learner-packs/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"student_id": 1,
"template_id": 1,
"selected_result_refs": [],
"generation_options": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/learner-packs/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"student_id": 1,
"template_id": 1,
"selected_result_refs": [],
"generation_options": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/learner-packs/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"student_id": 1,
"template_id": 1,
"selected_result_refs": [],
"generation_options": "example"
}),
});
/api/v1/learner-packs/jobs/{job_id}
Learner pack job status and rendered document
Requires the `marking` scope.
/api/v1/learner-packs/jobs/{job_id}/cancel
Cancel a learner-pack job and refund unused credits
Requires the `marking` scope.
/api/v1/media-marker/jobs
Queue video or audio marking
Requires the `media` scope.
| Body field | Type | Required |
|---|---|---|
criteria |
string | yes |
media_base64 |
string | yes |
filename |
string | no |
education_level |
string | no |
persona |
string | no |
presentation_type |
string | no |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/media-marker/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"criteria": "example",
"media_base64": "UEsDBBQAAAAA",
"filename": "example",
"education_level": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/media-marker/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"criteria": "example",
"media_base64": "UEsDBBQAAAAA",
"filename": "example",
"education_level": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/media-marker/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"criteria": "example",
"media_base64": "UEsDBBQAAAAA",
"filename": "example",
"education_level": "example"
}),
});
/api/v1/media-marker/jobs/{job_id}
Media marking job status and feedback
Requires the `media` scope.
/api/v1/media-marker/jobs/{job_id}/cancel
Cancel a media-marker job and refund unused credits
Requires the `media` scope.
/api/v1/reference-check/jobs
Queue the full reference-check web pipeline
Requires the `integrity` scope.
| Body field | Type | Required |
|---|---|---|
document_text |
string | yes |
style |
string | no |
enable_semantic_check |
boolean | no |
match_refs |
boolean | no |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/reference-check/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_text": "example",
"style": "example",
"enable_semantic_check": false,
"match_refs": false
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/reference-check/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"document_text": "example",
"style": "example",
"enable_semantic_check": false,
"match_refs": false
},
)
await fetch("https://feedbackflows.org/api/v1/reference-check/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"document_text": "example",
"style": "example",
"enable_semantic_check": false,
"match_refs": false
}),
});
/api/v1/reference-check/jobs/{job_id}
Reference-check job status and report
Requires the `integrity` scope.
/api/v1/reference-check/jobs/{job_id}/cancel
Cancel a reference-check job and refund unused credits
Requires the `integrity` scope.
/api/v1/rubric-marking/jobs
Queue rubric marking for a class ZIP
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
rubric_id |
integer | yes |
zip_base64 |
string | yes |
filename |
string | no |
marking_style |
string | no |
grading_system |
string | no |
callback_url |
string | no |
credit_check_only |
boolean | no |
curl -X POST https://feedbackflows.org/api/v1/rubric-marking/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rubric_id": 1,
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"marking_style": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/rubric-marking/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"rubric_id": 1,
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"marking_style": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/rubric-marking/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"rubric_id": 1,
"zip_base64": "UEsDBBQAAAAA",
"filename": "example",
"marking_style": "example"
}),
});
/api/v1/rubric-marking/jobs/{job_id}
Rubric marking job status and results
Requires the `marking` scope.
/api/v1/rubric-marking/jobs/{job_id}/cancel
Cancel a rubric marking job and refund unused credits
Requires the `marking` scope.
/api/v1/smart-essay/jobs
Queue essay marking (preferred over the synchronous endpoint)
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
essay_text |
string | yes |
marking_criteria |
string | yes |
education_level |
string | no |
persona |
string | no |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/smart-essay/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"essay_text": "example",
"marking_criteria": "example",
"education_level": "example",
"persona": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/smart-essay/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"essay_text": "example",
"marking_criteria": "example",
"education_level": "example",
"persona": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/smart-essay/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"essay_text": "example",
"marking_criteria": "example",
"education_level": "example",
"persona": "example"
}),
});
/api/v1/smart-essay/jobs/{job_id}
Essay marking job status and feedback
Requires the `marking` scope.
/api/v1/smart-essay/jobs/{job_id}/cancel
Cancel a smart-essay job and refund unused credits
Requires the `marking` scope.
/api/v1/worksheets/jobs
Queue worksheet generation
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
student_id |
integer | yes |
weaknesses_list |
array | no |
format |
string | no |
level |
string | no |
num_questions |
integer | no |
callback_url |
string | no |
curl -X POST https://feedbackflows.org/api/v1/worksheets/jobs \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"student_id": 1,
"weaknesses_list": [
"Clarity"
],
"format": "example",
"level": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/worksheets/jobs",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"student_id": 1,
"weaknesses_list": [
"Clarity"
],
"format": "example",
"level": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/worksheets/jobs", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"student_id": 1,
"weaknesses_list": [
"Clarity"
],
"format": "example",
"level": "example"
}),
});
/api/v1/worksheets/jobs/{job_id}
Worksheet job status and result
Requires the `marking` scope.
/api/v1/worksheets/jobs/{job_id}/cancel
Cancel a worksheet job and refund unused credits
Requires the `marking` scope.
/api/v1/automarking/jobs/{job_id}/export.csv
Export automarking results as CSV
Requires the `marking` scope.
/api/v1/automarking/results/{result_id}/export.pdf
Export one automarking result as PDF
Requires the `marking` scope.
/api/v1/classes/{class_id}/export.csv
Export a class roster as CSV
Requires the `analytics` scope.
/api/v1/learner-packs/jobs/{job_id}/export.pdf
Export a learner pack as PDF
Requires the `marking` scope.
/api/v1/media-marker/jobs/{job_id}/export.pdf
Export a media-marker report
Requires the `media` scope.
/api/v1/reference-check/jobs/{job_id}/export.pdf
Export a reference-check report as PDF
Requires the `integrity` scope.
/api/v1/rubric-marking/jobs/{job_id}/export.csv
Export rubric batch results as CSV
Requires the `marking` scope.
/api/v1/rubric-marking/results/{result_id}/export.pdf
Export one rubric result as PDF
Requires the `marking` scope.
/api/v1/smart-essay/jobs/{job_id}/export.pdf
Export a smart-essay report as PDF
Requires the `marking` scope.
/api/v1/worksheets/jobs/{job_id}/export.pdf
Export a completed worksheet as PDF
Requires the `marking` scope.
/api/v1/classes
List classes
/api/v1/classes
Create a class
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
name |
string | yes |
subject |
string | no |
curl -X POST https://feedbackflows.org/api/v1/classes \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "example",
"subject": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/classes",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"name": "example",
"subject": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/classes", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "example",
"subject": "example"
}),
});
/api/v1/classes/{class_id}
Update a class
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
name |
string | no |
subject |
string | no |
concluded |
boolean | no |
curl -X PATCH https://feedbackflows.org/api/v1/classes/{class_id} \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "example",
"subject": "example",
"concluded": false
}'
import os, requests
requests.patch(
"https://feedbackflows.org/api/v1/classes/{class_id}",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"name": "example",
"subject": "example",
"concluded": false
},
)
await fetch("https://feedbackflows.org/api/v1/classes/{class_id}", {
method: "PATCH",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "example",
"subject": "example",
"concluded": false
}),
});
/api/v1/classes/{class_id}/assignments
List assignments for a class
/api/v1/classes/{class_id}/assignments/{assignment_id}/results
Per-student outcomes for one assignment
Requires the `analytics` scope.
/api/v1/classes/{class_id}/results
Bulk export marking outcomes for a class
Requires the `analytics` scope.
/api/v1/classes/{class_id}/students
Add or remove students from a class
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
add_student_ids |
array | no |
remove_student_ids |
array | no |
curl -X PATCH https://feedbackflows.org/api/v1/classes/{class_id}/students \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"add_student_ids": [],
"remove_student_ids": []
}'
import os, requests
requests.patch(
"https://feedbackflows.org/api/v1/classes/{class_id}/students",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"add_student_ids": [],
"remove_student_ids": []
},
)
await fetch("https://feedbackflows.org/api/v1/classes/{class_id}/students", {
method: "PATCH",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"add_student_ids": [],
"remove_student_ids": []
}),
});
/api/v1/question-templates
List question templates
Requires the `marking` scope.
/api/v1/rubrics
List rubrics
/api/v1/rubrics
Create a rubric
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
name |
string | yes |
criteria |
string | yes |
marking_guidance |
string | no |
pass_rate |
integer | no |
max_attempts |
integer | no |
curl -X POST https://feedbackflows.org/api/v1/rubrics \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "example",
"criteria": "example",
"marking_guidance": "example",
"pass_rate": 1
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/rubrics",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"name": "example",
"criteria": "example",
"marking_guidance": "example",
"pass_rate": 1
},
)
await fetch("https://feedbackflows.org/api/v1/rubrics", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "example",
"criteria": "example",
"marking_guidance": "example",
"pass_rate": 1
}),
});
/api/v1/rubrics/{rubric_id}
Get one rubric with its criteria
/api/v1/students
List students
/api/v1/students
Create a student
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
name |
string | yes |
uln |
string | no |
class_ids |
array | no |
curl -X POST https://feedbackflows.org/api/v1/students \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "example",
"uln": "example",
"class_ids": []
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/students",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"name": "example",
"uln": "example",
"class_ids": []
},
)
await fetch("https://feedbackflows.org/api/v1/students", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "example",
"uln": "example",
"class_ids": []
}),
});
/api/v1/students/{student_id}
Update a student
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
name |
string | no |
uln |
string | no |
class_ids |
array | no |
curl -X PATCH https://feedbackflows.org/api/v1/students/{student_id} \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "example",
"uln": "example",
"class_ids": []
}'
import os, requests
requests.patch(
"https://feedbackflows.org/api/v1/students/{student_id}",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"name": "example",
"uln": "example",
"class_ids": []
},
)
await fetch("https://feedbackflows.org/api/v1/students/{student_id}", {
method: "PATCH",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "example",
"uln": "example",
"class_ids": []
}),
});
/api/v1/students/{student_id}/ai-history
AI detection history for one student
/api/v1/students/{student_id}/submissions
Marking results and detector runs for one student
Requires the `analytics` scope.
/api/v1/students/bulk
Create up to 200 students in one call (JSON array, {students: []}, or CSV)
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
students |
array | no |
curl -X POST https://feedbackflows.org/api/v1/students/bulk \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"students": []
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/students/bulk",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"students": []
},
)
await fetch("https://feedbackflows.org/api/v1/students/bulk", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"students": []
}),
});
/api/v1/students:bulk
Create up to 200 students in one call (JSON array, {students: []}, or CSV)
Requires the `marking` scope.
| Body field | Type | Required |
|---|---|---|
students |
array | no |
curl -X POST https://feedbackflows.org/api/v1/students:bulk \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"students": []
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/students:bulk",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"students": []
},
)
await fetch("https://feedbackflows.org/api/v1/students:bulk", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"students": []
}),
});
/api/v1/classes/{class_id}/assignments/{assignment_id}/analyze
Cohort analysis for one assignment
Requires the `analytics` scope.
/api/v1/students/{student_id}/progress-report
Generate a progress report for one student
Requires the `analytics` scope.
| Body field | Type | Required |
|---|---|---|
start_date |
string | no |
end_date |
string | no |
curl -X POST https://feedbackflows.org/api/v1/students/{student_id}/progress-report \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"start_date": "example",
"end_date": "example"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/students/{student_id}/progress-report",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"start_date": "example",
"end_date": "example"
},
)
await fetch("https://feedbackflows.org/api/v1/students/{student_id}/progress-report", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"start_date": "example",
"end_date": "example"
}),
});
/api/v1/usage
Usage and credit consumption for this account's API keys
Requires the `analytics` scope.
/api/v1/webhooks/test
Send a signed ping webhook to verify your receiver
| Body field | Type | Required |
|---|---|---|
callback_url |
string | yes |
curl -X POST https://feedbackflows.org/api/v1/webhooks/test \
-H "X-API-Key: $FEEDBACKFLOWS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"callback_url": "https://example.com/webhooks/feedbackflows"
}'
import os, requests
requests.post(
"https://feedbackflows.org/api/v1/webhooks/test",
headers={"X-API-Key": os.environ["FEEDBACKFLOWS_API_KEY"]},
json={
"callback_url": "https://example.com/webhooks/feedbackflows"
},
)
await fetch("https://feedbackflows.org/api/v1/webhooks/test", {
method: "POST",
headers: {
"X-API-Key": process.env.FEEDBACKFLOWS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
"callback_url": "https://example.com/webhooks/feedbackflows"
}),
});
Job POSTs accept callback_url. Completions are signed with X-FeedbackFlows-Signature: t=<unix>,v1=<hex> over <timestamp>.<raw-body>. Also sent: X-FeedbackFlows-Delivery and X-FeedbackFlows-Timestamp. Reject timestamps older than five minutes. Use POST /webhooks/test to ping your receiver (5 per hour).
import hmac, hashlib, time
def valid(header, body: bytes, secret: str, now=None) -> bool:
parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p)
ts, sig = int(parts["t"]), parts["v1"]
if abs((now or time.time()) - ts) > 300:
return False
expected = hmac.new(secret.encode(), f"{ts}.".encode() + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(sig, expected)
JSON bodies use error, code, status and request_id. Look for X-Request-Id on every response.
| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Malformed JSON or missing fields |
| 401 | UNAUTHORIZED / KEY_EXPIRED | Missing, invalid, or expired key |
| 402 | INSUFFICIENT_CREDITS | Not enough credits |
| 403 | SCOPE_FORBIDDEN | Key lacks the required scope |
| 404 | NOT_FOUND | Unknown resource |
| 429 | RATE_LIMITED | See Retry-After |
| 500 | INTERNAL_ERROR | Unexpected failure |