Skip to content

Content-injection-only flow

Content-injection = a partner (or an internal pipeline) that only wants to push content into Itera programmatically, without full instructor seats or a UI. In v1 this is not a separate permission — it is a use-case of the author role using the same itera-mcp create_* / instantiate_program tools.

  1. Provision an Itera account with author on the target tenant (ask your Itera admin). Store its refresh token in your pipeline’s secret store.
  2. Mint a fresh access token at run time (Supabase password grant, or refresh via the MCP’s /auth/refresh proxy — see Getting started → token refresh).
  3. Connect to itera-mcp with that token (or call the tools over raw HTTP — see the raw HTTP tab).
  4. Idempotency is on you: slug is unique per tenant, so a re-run of create_program with the same slug returns a conflict (23505). Either catch it, or list_programs first and branch to update_program when the slug already exists.

A typical injector maps rows from your CMS/spreadsheet to the graph:

for each course in source:
program = create_program(tenant_id, slug=course.slug, title_i18n=course.title)
for each section in course.sections:
unit = create_unit(program.id, ordinal=section.i, title_i18n=section.title)
for each class in section.classes:
lesson = create_lesson(unit.id, ordinal=class.i, title_i18n=class.title)
for each step in class.steps:
create_activity(lesson.id, kind=step.kind, ordinal=step.i,
spec=step.spec, rubric=step.rubric)

Keep a stable mapping from your source ids → returned Itera ids so re-runs update_* instead of duplicating.

If every injected course derives from one master template, author the template once and instantiate_program per target — one call copies the whole graph, then update_* the copies with the per-course specifics.