Resources
Content Integration Examples

Content Integration Examples

Copy-ready curl, Node.js, and Python examples for Content Integration.

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.json

curl: 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": {}
}