Kit version 0.1.0
Technical reference
Product A (for example an assessment app) records learner events. The Seneca SDK transforms them inside Product A, and only allowlisted, pseudonymous evidence is sent to Seneca. Product B (for example a tutoring app) asks Seneca for context for one purpose, under the learner's authorization, and decides what to do with it. Product A and Product B never connect.
This kit shows that flow with synthetic data: four worked examples (one of them for writing), a reference transform that runs in this page and in Node, three JSON Schemas and a Product B example.
Sandbox evaluation only. Synthetic data only, no production use, no redistribution. Full terms: LICENSE.md. The kit uses its own teaching formats. Seneca's production integration format is shared in a sandbox under a pilot agreement.
1. Quickstart
Node 18 or later. No install, no dependencies, no network calls.
The zip is assembled in your browser from the files in section 8.
cd seneca-starter-kit
node kit/cli.mjs --check # run every example, check every schema
node kit/cli.mjs examples/app-to-app/product-a-export.csv # transform one file
node kit/product-b-start.mjs # plan a first session from a context file
python python/product_b_start.py # the same, in Python
node kit/cli.mjs --suggest your-export.csv > mapping.json # map a CSV with its own column names
2. Flow
Product A ── raw events ──> SDK transform ── evidence ──> Seneca record
(stays in A) (runs inside A) (sent) │
│ learner authorizes
│ one recipient, one purpose
Product B <──────────────── context (summary + limits) ───────────┘
Product A x Product B: no connection, no shared learner IDs, no item-level rows.
- Evidence (what leaves Product A): outcomes, scores, timing, attempts, help used, skill tags, timestamps. Learner, session and item IDs become pseudonyms. Everything else stays in Product A and is listed by name.
- Record (what Seneca keeps): observations, Product A's own judgments kept under Product A's name, Seneca's readings with a confidence level, provenance, scope and limitations.
- Context (what Product B receives): a summary for one purpose, its own learner reference,
may_use_foranddo_not_infer. No rows, item IDs or content from Product A.
3. Worked examples
3.1 Product A input
Struck-through fields stay in Product A.
3.2 Evidence (computed in this page)
Output of kit/transform.mjs on the input above. Left behind:
evidence.jsonDownload
3.3 Seneca record (illustrative)
Hand-written to show the shape. How Seneca forms readings and confidence is not described.
seneca-record.jsonDownload
3.4 Product B request and context (illustrative)
No public endpoint. Context reads are set up per integration in a pilot. Note that learner_ref differs from the record's: each recipient gets its own.
product-b-request.json
product-b-context.jsonDownload
4. Input formats
| Format | Detected by | What the kit reads |
|---|---|---|
| JSON export | object with responses[] | export, student.id, session, skill_labels, skill_report[], and per response question_id, skill_tag, outcome, points, max_points, seconds, attempt, hint_used or assistance, answered_at |
| JSON export (writing) | object with submissions[] | export, student.id, assignments (label, genre, setting), criteria (label), and per submission submission_id, assignment_id, draft, revises, submitted_at, word_count, ai_assistance, scores[] (criterion, score, max, rater.role, scored_at) |
| JSON rows | an array of flat objects | read like CSV rows: keys become columns (use a column mapping if they aren't the kit's names); keys holding nested objects are left behind |
| CSV | header row with commas | required learner_id, item_id, occurred_at; optional session_id, skill_tag, skill_label, aligned_to, item_type, outcome, points, max_points, seconds, attempt, assistance, setting, timed, self_rating |
| xAPI 2.0.0 / 1.0.3 | statement(s) with actor, verb, object | account actor; ADL answered or completed; result.success, result.score (raw/min/max), result.duration; first category activity as skill; registration as session |
| Caliper 1.2 | envelope with sensor and data[] | AssessmentItemEvent (Completed) and GradeEvent (Graded, with a Score) |
5. Transform rules
- Allowlist only. Any field the transform doesn't read stays in Product A and is reported by name with a reason (
identity,content,not needed for this purpose,not in the kit allowlist). - Learner, session and item IDs become pseudonyms (
lrn_,ses_,itm_). The kit uses an unkeyed demo hash; production references are keyed and differ per recipient. - A payload containing what looks like an email address, phone number or national ID number is refused before anything is read.
- Writing: the text never leaves. Essays, prompts and comments are left behind. Every score becomes a judgment attributed to its rater (
teacher,ai_grader,peerorself); a score without a rater role is refused. A revision must point to an earlier draft in the same payload. - A CSV, or a JSON array of flat rows, with its own column names can be read through a column mapping (
seneca-starter-mapping@0.1, schema): which of your columns is which kit field, how your value labels translate (for exampleRighttocorrect), and a timezone for timestamps that have none. Unmatched columns stay behind. Try it in section 7, or runnode kit/cli.mjs --suggest your-export.csv. - One learner per payload. Up to 2,000 events and 1 MiB (500 events per Caliper envelope).
- Nothing is guessed. A score without right/wrong stays
not_reported; self-ratings stayself_reported; completion-only events staycompletion_only; unreported help staysunknown. - Unsupported shapes fail with a code:
UNSUPPORTED_VERB,UNSUPPORTED_ACTOR,UNSUPPORTED_EVENT,UNSUPPORTED_VERSION,MULTIPLE_LEARNERS,INVALID_FIELD,INVALID_TIME,INVALID_MAPPING,PERSONAL_DATA.
6. Output formats
| Format | Produced by | Schema |
|---|---|---|
seneca-starter-evidence@0.1 | the transform (step 3.2) | starter-evidence.schema.json |
seneca-starter-record@0.1 | illustrative (step 3.3) | starter-record.schema.json |
seneca-starter-context@0.1 | illustrative (step 3.4) | starter-context.schema.json |
seneca-starter-mapping@0.1 | you (section 7 or --suggest) | starter-mapping.schema.json |
seneca-starter-context-preview@0.1 | previewContext(): counts and limits only | none |
These are teaching formats. They are not Seneca's production contract.
7. Try it in the browser
Paste a synthetic payload in any of the five formats, or a CSV (or JSON array of rows) with your own column names and use Map my columns. The transform runs in this tab. Nothing you paste is uploaded or stored. The only thing the page sends is an anonymous count that the tester was used, never what you pasted.
Map your columns
Match your export's columns to the kit's fields. Suggestions are filled in; check them. Columns you leave unmatched stay in your product and are listed by name. Nothing leaves this tab.
| Kit field | Your column | Your values → kit values |
|---|
Sending us a made-up export? Attach the mapping file too, and we can map it faster.
Load a sample or paste a payload, then press Transform locally.
8. Files
9. What exists today
| Surface | Status |
|---|---|
| Seneca partner event format | Pilot. Served to approved pilot partners. Documentation and sandbox access come with the pilot agreement. |
| CSV exports | Pilot. Mapped to the partner event format during a pilot. |
| xAPI 2.0.0 and 1.0.3 | SDK only. Adapter for a defined subset (answered and completed statements). Hosted intake is not open yet. |
| 1EdTech Caliper 1.2 | SDK only. Adapter for AssessmentItemEvent (Completed) and GradeEvent (Graded). Hosted intake is not open yet. No certification is claimed. |
| Context reads for Product B | Pilot. Set up per integration. No public endpoint. |
| AI assistants over MCP | Live. Learner-authorized reads of the learner's own Seneca record at https://vindicaseneca.com/mcp. See Developers. |
| This kit's formats | Teaching only. Not the production contract. |
10. Before a pilot
Have these ready for a first call. None of it needs real student data.
- One kind of event to start with, for example answered questions in a diagnostic, and a made-up export of it in your real format. If it's a CSV, attach the
mapping.jsonfrom section 7. - How learners are identified in your product (account IDs, never names or emails), and where in your app a learner would connect Seneca.
- Which direction: sending evidence, reading context for a first session, or both. For reading, the one purpose you'd ask for.
- Who your learners are: their age range and the countries they're in. Consent rules differ by age and country.
- Who owns it on your side, and when you'd want a pilot to start.
11. Contact
Email kevinchoi@vindicaseneca.com to review an integration, send a synthetic example for mapping, or discuss a paid pilot with sandbox access. Synthetic data only, please.
We count visits and tool use anonymously: no cookies, no identifiers, and never anything you type or paste. Browsers that send Global Privacy Control or Do Not Track are not counted.