These examples show the full path from key creation to result retrieval.
curl: create key
curl -X POST "https://api.tutorflow.io/v1/content/organizations/{organizationId}/api-keys" \
-H "Content-Type: application/json" \
-b tutorflow-admin.cookies \
-d '{"name":"external-content-test","rateLimitPerMinute":60}'curl: create expansion
curl -X POST "https://api.tutorflow.io/v1/content/integrations/expansions" \
-H "Authorization: Bearer $TUTORFLOW_CONTENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: language-basics-level-a1-2026-07-04" \
--data-binary @source-content.jsoncurl: poll and retrieve
curl "https://api.tutorflow.io/v1/content/integrations/expansions/$JOB_ID" \
-H "Authorization: Bearer $TUTORFLOW_CONTENT_API_KEY"
curl "https://api.tutorflow.io/v1/content/integrations/expansions/$JOB_ID/result" \
-H "Authorization: Bearer $TUTORFLOW_CONTENT_API_KEY"Node.js: create expansion
const response = await fetch(
'https://api.tutorflow.io/v1/content/integrations/expansions',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TUTORFLOW_CONTENT_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'language-basics-level-a1-2026-07-04',
},
body: JSON.stringify({
requestedOutputs: ['interactive_module', 'summary_video', 'expanded_quiz'],
payload: {
category: { id: 'language-basics', title: 'Language Basics' },
language: 'en',
level: {
id: 'level-a1',
title: 'A1 Foundations',
lessons: [
{
id: 'lesson-vocabulary-1',
type: 'vocabulary',
title: 'Basic greetings',
items: [{ term: 'hello', meaning: 'a greeting' }],
},
],
},
},
}),
},
)
const job = await response.json()Node.js: polling helper
async function waitForContentJob(jobId) {
for (let attempt = 0; attempt < 60; attempt++) {
const response = await fetch(
`https://api.tutorflow.io/v1/content/integrations/expansions/${jobId}`,
{
headers: {
Authorization: `Bearer ${process.env.TUTORFLOW_CONTENT_API_KEY}`,
},
},
)
const job = await response.json()
if (job.status === 'completed' || job.status === 'failed') {
return job
}
await new Promise((resolve) => setTimeout(resolve, 3000))
}
throw new Error('Content job did not finish within the polling window')
}Python: create expansion
import os
import requests
response = requests.post(
"https://api.tutorflow.io/v1/content/integrations/expansions",
headers={
"Authorization": f"Bearer {os.environ['TUTORFLOW_CONTENT_API_KEY']}",
"Content-Type": "application/json",
"Idempotency-Key": "language-basics-level-a1-2026-07-04",
},
json={
"requestedOutputs": ["interactive_module", "summary_video", "expanded_quiz"],
"payload": {
"category": {"id": "language-basics", "title": "Language Basics"},
"language": "en",
"level": {
"id": "level-a1",
"title": "A1 Foundations",
"lessons": [
{
"id": "lesson-vocabulary-1",
"type": "vocabulary",
"title": "Basic greetings",
"items": [{"term": "hello", "meaning": "a greeting"}],
}
],
},
},
},
timeout=30,
)
response.raise_for_status()
job = response.json()Manifest storage shape
{
"sourceContentId": "language-basics:level-a1",
"tutorFlowJobId": "3f9440c4-7b15-48d7-a02f-4c1c50a8c3e1",
"outputType": "interactive_module",
"status": "completed",
"resourceType": "module",
"resourceId": null,
"manifest": {}
}