For AI agents: a documentation index is available at https://developers.jarsave.com/llms.txt, this page as Markdown at https://developers.jarsave.com/links.md, and the OpenAPI description at https://developers.jarsave.com/openapi.json.
The link object
v1A link joins one of your students to one child in JarSave. Every item you send goes to a link. The parent starts it with a code, confirms it, and can end it at any time; so can you.
Attributes
id string
Unique identifier for the link, starting with lnk_.
object string, value is "link"
The object's type.
student_id string
Your student number, as you sent it.
student_name string
The student's full name as your reports and certificates print it.
status enum
pending until the parent confirms, then active. revoked once either side ends it.
created timestamp
When you created the link.
confirmed_at timestamp, nullable
When the parent confirmed it in JarSave.
revoked_at timestamp, nullable
When the link ended.
revoked_by enum, nullable
parent or course.
The link object
{
"id": "lnk_8Gm2QxT4",
"object": "link",
"student_id": "STD-1024",
"student_name": "Ayu Lestari Putri",
"status": "active",
"created": "2026-11-20T15:04:11+07:00",
"confirmed_at": "2026-11-20T15:06:40+07:00",
"revoked_at": null,
"revoked_by": null
}Create a link
POST /v1/links
Turns the parent's one-time code into a link. The code is 8 characters, works once and expires 24 hours after JarSave shows it. JarSave then asks the parent to confirm that this student, at your course, is their child. The link is pending until they do.
In the sandbox, make codes and confirm links from code with the test helpers, or with Make a test link code and Confirm as parent in the dashboard.
Parameters
code string Required
The one-time code the parent gave you, for example K7PM-Q2XD. Dashes and case do not matter.
student_id string Required
Your student number. Items name the student by the link, not by this number.
student_name string Required
The full name as printed on your reports and certificates. The parent sees it when confirming.
Returns
The link object, with status pending. A code that is wrong, used or expired returns 400 with error.field set to code.
Request
curl https://api.jarsave.com/v1/links \
-H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
-H "JarSave-Version: 2026-10-29" \
-H "Content-Type: application/json" \
-d '{"code": "K7PM-Q2XD", "student_id": "STD-1024", "student_name": "Ayu Lestari Putri"}'use Illuminate\Support\Facades\Http;
// config/services.php: 'jarsave' => ['key' => env('JARSAVE_SECRET_KEY')]
$response = Http::withToken(config('services.jarsave.key'))
->withHeaders(['JarSave-Version' => '2026-10-29'])
->post('https://api.jarsave.com/v1/links', [
'code' => 'K7PM-Q2XD',
'student_id' => 'STD-1024',
'student_name' => 'Ayu Lestari Putri',
]);const response = await fetch("https://api.jarsave.com/v1/links", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.JARSAVE_SECRET_KEY}`,
"JarSave-Version": "2026-10-29",
"Content-Type": "application/json",
},
body: JSON.stringify({
code: "K7PM-Q2XD",
student_id: "STD-1024",
student_name: "Ayu Lestari Putri",
}),
});
const result = await response.json();import os
import requests
response = requests.post(
"https://api.jarsave.com/v1/links",
headers={
"Authorization": f"Bearer {os.environ['JARSAVE_SECRET_KEY']}",
"JarSave-Version": "2026-10-29",
},
json={
"code": "K7PM-Q2XD",
"student_id": "STD-1024",
"student_name": "Ayu Lestari Putri",
},
timeout=30,
)
result = response.json()Response
{
"id": "lnk_8Gm2QxT4",
"object": "link",
"student_id": "STD-1024",
"student_name": "Ayu Lestari Putri",
"status": "pending",
"created": "2026-11-20T15:04:11+07:00",
"confirmed_at": null,
"revoked_at": null,
"revoked_by": null
}Retrieve a link
GET /v1/links/:id
Returns the link, so you can see whether the parent has confirmed it or ended it. Check it before sending a batch of past items.
Returns
The link object, or 404 if no link with that id belongs to your course.
Request
curl https://api.jarsave.com/v1/links/lnk_8Gm2QxT4 \
-H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
-H "JarSave-Version: 2026-10-29"use Illuminate\Support\Facades\Http;
// config/services.php: 'jarsave' => ['key' => env('JARSAVE_SECRET_KEY')]
$response = Http::withToken(config('services.jarsave.key'))
->withHeaders(['JarSave-Version' => '2026-10-29'])
->get('https://api.jarsave.com/v1/links/lnk_8Gm2QxT4');const response = await fetch("https://api.jarsave.com/v1/links/lnk_8Gm2QxT4", {
headers: {
Authorization: `Bearer ${process.env.JARSAVE_SECRET_KEY}`,
"JarSave-Version": "2026-10-29",
},
});
const result = await response.json();import os
import requests
response = requests.get(
"https://api.jarsave.com/v1/links/lnk_8Gm2QxT4",
headers={
"Authorization": f"Bearer {os.environ['JARSAVE_SECRET_KEY']}",
"JarSave-Version": "2026-10-29",
},
timeout=30,
)
result = response.json()Revoke a link
DELETE /v1/links/:id
Ends the link, for example when the student leaves your course. Items sent afterwards return 410. When the parent ends a link in JarSave, your next request for it returns 410 too.
Returns
The link object, with status revoked and revoked_by set to course.
Request
curl -X DELETE https://api.jarsave.com/v1/links/lnk_8Gm2QxT4 \
-H "Authorization: Bearer $JARSAVE_SECRET_KEY" \
-H "JarSave-Version: 2026-10-29"use Illuminate\Support\Facades\Http;
// config/services.php: 'jarsave' => ['key' => env('JARSAVE_SECRET_KEY')]
$response = Http::withToken(config('services.jarsave.key'))
->withHeaders(['JarSave-Version' => '2026-10-29'])
->delete('https://api.jarsave.com/v1/links/lnk_8Gm2QxT4');const response = await fetch("https://api.jarsave.com/v1/links/lnk_8Gm2QxT4", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.JARSAVE_SECRET_KEY}`,
"JarSave-Version": "2026-10-29",
},
});
const result = await response.json();import os
import requests
response = requests.delete(
"https://api.jarsave.com/v1/links/lnk_8Gm2QxT4",
headers={
"Authorization": f"Bearer {os.environ['JARSAVE_SECRET_KEY']}",
"JarSave-Version": "2026-10-29",
},
timeout=30,
)
result = response.json()