2026-10-29 API Reference jarsave.com Get keys

Course Feed API

The Course Feed API lets a course, class or academy send a student's progress to the student's parents in JarSave: classes attended, lessons completed, term reports, certificates and badges. Every course uses the same API, so a course connects once and every family that asks is covered.

You only make calls to JarSave. You host nothing, and you need no parent portal or OAuth server.

  1. A parent opens JarSave and gets a one-time link code for their child.
  2. The parent gives the code to you, in your student portal or to your admin.
  3. You create a link with the code and your student number. The parent confirms it in JarSave.
  4. You send the student's past items once, then each new item as it happens.
  5. The parent approves each item in JarSave. Nothing reaches the child's record without that tap.

The API accepts and returns JSON over HTTPS. Times are ISO 8601 with an offset; dates are YYYY-MM-DD.

Base URL

https://api.jarsave.com/v1

Not a developer?

Forward this page to the person who runs your learning system. Keys are in the dashboard; questions go to [email protected].

Authentication

Each course has two secret keys: a sandbox key that starts with sk_test_ and a live key that starts with sk_live_. Send the key as a bearer token on every request, with the API version you built against.

Sign up in the dashboard with your work email and your sandbox key is there at once. A sandbox key reaches only test students: the dashboard's Test family plays the parent. A live key is issued after one test link works end to end and JarSave has checked the business behind the course.

Keep keys on your server. A key in an app or a web page can be copied, and anything sent with it would carry your course's name. The examples on this page read it from JARSAVE_SECRET_KEY, an environment variable on your server.

Authenticated request

curl https://api.jarsave.com/v1/links/lnk_8Gm2QxT4 \
  -H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
  -H "JarSave-Version: 2026-10-29"

Errors

JarSave answers with a standard HTTP status. A 2xx means the item was received. A 4xx means something in the request needs fixing, and the body says what. A 5xx is on our side: retry later with the same request.

StatusMeaning
200, 201Received. 201 when the object is new, 200 when it replaced one with the same id.
400A field is missing or invalid. error.field names it.
401The key is missing, wrong or revoked.
404No link with that id belongs to your course.
409The link is still waiting for the parent to confirm it. Send the item again later.
410The link was revoked. Stop sending for this student.
429Too many requests. Wait for the seconds in Retry-After.
500, 503Something failed at JarSave. Retry with backoff.

Error response

{
  "error": {
    "type": "invalid_request",
    "field": "study_hours",
    "message": "study_hours must be a number of hours, for example 20."
  }
}

Idempotent requests

Every item you send carries your own id for it: session_id, lesson_id, report_id, certificate_no or badge_id. Sending the same id again for the same link never creates a second item, so a retry after a timeout is always safe.

If the body has changed, JarSave treats it as a correction: it replaces the item and shows the parent what changed.

Good to know

Ids are unique per course and per kind of item. Use the ids your system already has; JarSave does not need new ones.

Versioning

Send JarSave-Version with the date of the version you built against. The current version is 2026-10-29.

New optional fields can appear in any version. A change that could break an integration comes as a new dated version, and requests that send the old date keep the old behaviour.

Header

JarSave-Version: 2026-10-29

The attendance object

v1

One class session and whether the student came. Send one for every session on the student's timetable, including absences, so the parent sees the whole term. In JarSave a session the child attended counts as a practice day for that subject.

Attributes

session_id string Required

Your id for this session. Sending it again replaces the item (see idempotent requests).

course_id string Required

Your id for the course.

course_name string Required

The course as the parent knows it, for example Junior Coding 2.

subject string Required

What the course teaches, in one or two words: Coding, English, Piano.

starts_at timestamp Required

When the session started, with its offset, for example 2026-11-26T15:00:00+07:00.

ends_at timestamp Required

When it ended.

mode enum Required

in_person or online.

status enum Required

present, late, absent or excused.

meeting_no integer, nullable

The session's number in the course, for example 14 of 21.

The attendance object

{
  "session_id": "ses_55120",
  "course_id": "crs_junior_coding_2",
  "course_name": "Junior Coding 2",
  "subject": "Coding",
  "starts_at": "2026-11-26T15:00:00+07:00",
  "ends_at": "2026-11-26T16:30:00+07:00",
  "mode": "in_person",
  "status": "present",
  "meeting_no": 6
}

Send attendance

POST/v1/links/:id/attendance

Send each session once attendance is taken, the same day. For the history, send the past sessions of the current course when the link becomes active.

Parameters

The attendance object's attributes. To send up to 100 at once, put them in an items array.

Returns

The item with its JarSave id, the link, status pending (waiting for the parent) and received. With items, a list: {"object": "list", "data": [...]}, one entry per item in the order sent.

Request

curl https://api.jarsave.com/v1/links/lnk_8Gm2QxT4/attendance \
  -H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
  -H "JarSave-Version: 2026-10-29" \
  -H "Content-Type: application/json" \
  -d @session.json

Response

{
  "id": "itm_3Rk9Vb2W",
  "object": "attendance",
  "link": "lnk_8Gm2QxT4",
  "session_id": "ses_55120",
  "status": "pending",
  "received": "2026-11-26T16:41:02+07:00"
}

The lesson object

v1

A lesson the student finished, with its score when the lesson is graded. In JarSave it shows the parent what the child built or learned that week.

Attributes

lesson_id string Required

Your id for this student's lesson.

course_id string Required

Your id for the course.

course_name string Required

The course as the parent knows it.

lesson_no integer Required

The lesson's number in the course.

title string Required

The lesson's title, for example Make the Robot Dance.

goals array of strings

What the lesson teaches, one short line each, as in your syllabus.

completed_at timestamp Required

When the student finished it.

score integer, nullable

0 to 100, only if the lesson is graded.

project_url string, nullable

A public page of what the student made, if your system has one. No photos of the child.

The lesson object

{
  "lesson_id": "les_77031",
  "course_id": "crs_junior_coding_2",
  "course_name": "Junior Coding 2",
  "lesson_no": 3,
  "title": "Make the Robot Dance",
  "goals": [
    "Learn what a loop is",
    "Move the robot with a loop"
  ],
  "completed_at": "2026-11-26T16:12:40+07:00",
  "score": 86,
  "project_url": null
}

Send a lesson

POST/v1/links/:id/lessons

Send a lesson when the student finishes it. Send one item per lesson, not one per quiz attempt: if the score changes later, send the same lesson_id again.

Parameters

The lesson object's attributes, or up to 100 of them in an items array.

Returns

The item with its JarSave id, link, status and received. With items, a list: {"object": "list", "data": [...]}, one entry per item in the order sent.

Request

curl https://api.jarsave.com/v1/links/lnk_8Gm2QxT4/lessons \
  -H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
  -H "JarSave-Version: 2026-10-29" \
  -H "Content-Type: application/json" \
  -d @lesson.json

Response

{
  "id": "itm_7Ha1Lc0P",
  "object": "lesson",
  "link": "lnk_8Gm2QxT4",
  "lesson_id": "les_77031",
  "status": "pending",
  "received": "2026-11-26T16:12:44+07:00"
}

The term report object

v1

The report a teacher writes at the end of a term or a block of meetings. Send its scores and teacher notes as fields, not only inside the PDF: JarSave reads them to give the parent ideas for helping at home.

Attributes

report_id string Required

Your id for this report.

course_id string Required

Your id for the course.

course_name string Required

The course as the parent knows it.

period_start date Required

The first day the report covers.

period_end date Required

The last day it covers.

meeting_from integer, nullable

The first meeting it covers, for example 14.

meeting_to integer, nullable

The last meeting it covers, for example 21.

issued_on date Required

The day the report was published.

criteria array of objects Required

One row per criterion the teacher assessed.

Show child attributes

name string Required

The criterion, for example Coding Concept & Practice.

score integer, nullable Required

0 to 100, or null if the criterion has only a grade.

grade string Required

The grade as printed, for example A.

teacher_note string Required

The teacher's words for this criterion, unedited.

lessons array of objects

The lesson scores the report lists.

Show child attributes

meeting_no integer Required

The meeting the lesson was in.

title string Required

The lesson's title.

score integer Required

0 to 100.

grade string Required

The grade as printed.

grading_scale array of objects Required

Your grades and what they mean, so the parent can read them.

Show child attributes

grade string Required

For example A.

min integer Required

The lowest score for this grade.

max integer Required

The highest score for this grade.

label string Required

For example Very Good.

summary object

Totals for the period, as the report prints them: hours, projects, skills_gained.

signed_by object Required

Who signed the report: name and role, for example Head of Teachers.

file_url string Required

The report as PDF. See files.

The term report object

{
  "report_id": "rpt_20931",
  "course_id": "crs_junior_coding_2",
  "course_name": "Junior Coding 2",
  "period_start": "2026-09-03",
  "period_end": "2026-10-22",
  "meeting_from": 1,
  "meeting_to": 7,
  "issued_on": "2026-10-29",
  "criteria": [
    {
      "name": "Coding Concept & Practice",
      "score": 92,
      "grade": "A",
      "teacher_note": "Uses loops with confidence and explains them in her own words."
    }
  ],
  "lessons": [
    { "meeting_no": 3, "title": "Make the Robot Dance", "score": 86, "grade": "A" }
  ],
  "grading_scale": [
    { "grade": "A", "min": 86, "max": 100, "label": "Very Good" },
    { "grade": "B", "min": 75, "max": 85, "label": "Good" }
  ],
  "summary": { "hours": 10.5, "projects": 4, "skills_gained": 3 },
  "signed_by": { "name": "Dewi Anggraini", "role": "Head of Teachers" },
  "file_url": "https://files.academy.example/r/20931.pdf?sig=..."
}

Send a term report

POST/v1/links/:id/reports

Send a report on the day you publish it to families. For the history, send every report of the student's courses so far when the link becomes active.

Parameters

The term report object's attributes, one report per request.

Returns

The item with its JarSave id, link, status and received.

Request

curl https://api.jarsave.com/v1/links/lnk_8Gm2QxT4/reports \
  -H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
  -H "JarSave-Version: 2026-10-29" \
  -H "Content-Type: application/json" \
  -d @report.json

Response

{
  "id": "itm_2Wd8Ms5N",
  "object": "report",
  "link": "lnk_8Gm2QxT4",
  "report_id": "rpt_20931",
  "status": "pending",
  "received": "2026-10-29T10:20:15+07:00"
}

The certificate object

v1

The certificate a student gets for finishing a course or passing a level. In JarSave it becomes a lasting entry in the child's record, so send the file the family would print, and a page that proves it is real.

Attributes

certificate_no string Required

The number printed on the certificate. It is the item's id.

course_id string Required

Your id for the course.

course_name string Required

The course or level as printed, for example Junior Coding 2.

subject string Required

What the course teaches, in one or two words: Coding, English, Piano.

level string, nullable

The level as printed, for example Level 2 or A2 Flyers.

started_on date Required

The first day of the course.

completed_on date Required

The day the student finished it.

issued_on date Required

The date printed on the certificate.

study_hours number Required

The course's teaching hours, as you publish them, for example 20.

final_grade string, nullable

The overall grade, only if the certificate prints one.

rank string, nullable

A place or distinction, only if the certificate prints one, for example 1st place.

issuer string Required

The course provider's legal name, as printed.

file_url string Required

The certificate as PDF or PNG. See files.

verify_url string, nullable

A public page on your site that confirms this certificate. A course that issues verifiable digital badges can send that badge's link.

The certificate object

{
  "certificate_no": "EXA-2026-004517",
  "course_id": "crs_junior_coding_2",
  "course_name": "Junior Coding 2",
  "subject": "Coding",
  "level": "Level 2",
  "started_on": "2026-09-03",
  "completed_on": "2027-01-28",
  "issued_on": "2027-02-01",
  "study_hours": 20,
  "final_grade": "A",
  "rank": null,
  "issuer": "PT Contoh Akademi Digital",
  "file_url": "https://files.academy.example/c/004517.pdf?sig=...",
  "verify_url": "https://academy.example/verify/EXA-2026-004517"
}

Send a certificate

POST/v1/links/:id/certificates

Send a certificate when it is issued. For the history, send every certificate the student already has when the link becomes active.

Parameters

The certificate object's attributes, one certificate per request.

Returns

The item with its JarSave id, link, status and received.

Request

curl https://api.jarsave.com/v1/links/lnk_8Gm2QxT4/certificates \
  -H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
  -H "JarSave-Version: 2026-10-29" \
  -H "Content-Type: application/json" \
  -d @certificate.json

Response

{
  "id": "itm_9Tq4Ze7A",
  "object": "certificate",
  "link": "lnk_8Gm2QxT4",
  "certificate_no": "EXA-2026-004517",
  "status": "pending",
  "received": "2027-02-01T09:02:31+07:00"
}

The badge object

v1

A badge or achievement the student earned in your system. Send only badges the student has earned, not the ones still locked.

Attributes

badge_id string Required

Your id for this student's badge.

name string Required

The badge's name, for example 3D Builder.

subject string Required

What it is for, in one or two words, for example Coding.

course_id string, nullable

The course it belongs to, if any.

image_url string Required

The badge picture, PNG or SVG, square, at least 256 pixels. See files.

earned_at timestamp Required

When the student earned it.

The badge object

{
  "badge_id": "bdg_3d_builder_1024",
  "name": "3D Builder",
  "subject": "Coding",
  "course_id": "crs_junior_coding_2",
  "image_url": "https://files.academy.example/b/3d-builder.png",
  "earned_at": "2027-01-28T16:30:00+07:00"
}

Send a badge

POST/v1/links/:id/badges

Send a badge when the student earns it, and every earned badge once when the link becomes active.

Parameters

The badge object's attributes, or up to 100 of them in an items array.

Returns

The item with its JarSave id, link, status and received. With items, a list: {"object": "list", "data": [...]}, one entry per item in the order sent.

Request

curl https://api.jarsave.com/v1/links/lnk_8Gm2QxT4/badges \
  -H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
  -H "JarSave-Version: 2026-10-29" \
  -H "Content-Type: application/json" \
  -d @badge.json

Files

Reports, certificates and badges carry a file link. JarSave downloads the file when it receives the item and keeps its own copy, so a signed link that expires is fine.

  • The link must work, without a login, for at least 24 hours after you send the item.
  • PDF, PNG, JPEG or SVG, up to 10 MB.
  • The file must name the student as student_name does. JarSave declines a file that names a different child and tells the parent why.

Good to know

If a file cannot be downloaded, the item returns 400 with error.field set to file_url. Send it again with a fresh link.

What JarSave does with it

JarSave is a family app: parents reward effort and learning, and their child keeps the record. The data you send is the child's, and the parent decides what happens to it.

  • Every item waits for the parent's approval before it reaches the child's record.
  • Either side can end a link, and nothing new arrives after that.
  • JarSave's assistant reads teacher notes to suggest how the parent can help at home. It receives the child's age only, never the name, school or teacher.
  • Data is stored in Singapore.

Not accepted

Send only the fields on this page. JarSave does not take:

Photos or videos of the child In-app coins or points Upcoming schedule Recommended courses Teacher names Branch or class group Parent contact details Payment or fees

Questions

Keys, a test family, or anything on this page: [email protected].

JarSave is run by PT Nadi Inovasi Nusantara, Indonesia.