Save and continue
Store partial form answers and resume later with a 14-day token.
Save and continue
When a form has allow_save_continue: true, a submitter can store their in-progress answers and come back later. The server keeps the partial state for 14 days and hands back an opaque partialId you use to restore it.
Both endpoints check that the form exists and that allow_save_continue is enabled. The partialId is bound to one form; a partialId from form A cannot read form B's state.
Save partial state
https://forms.hep.gg/api/v1/forms/public/:slug/partialPublicPass the answers collected so far. Omit partialId to create a new save; pass a partialId from an earlier save to overwrite that same row. Overwriting in place is what keeps autosave from piling up duplicate rows, so reuse the id you got back the first time.
datafield_key, same shape as a submit's data.currentPageIdid of the page the submitter is on, so a resume can land them back there.partialIdpartialId from a previous save for this form. When it matches an existing row, that row is updated in place; otherwise a new row is created.partialIdexpiresAtcurl -X POST https://forms.hep.gg/api/v1/forms/public/my-form/partial \
-H "Content-Type: application/json" \
-d '{
"data": { "your_name": "Ada" },
"currentPageId": "pg_1"
}'const base = "https://forms.hep.gg/api/v1/forms/public/my-form";
// First save: no partialId -> new row
let { data } = await fetch(`${base}/partial`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ data: { your_name: "Ada" }, currentPageId: "pg_1" }),
}).then((r) => r.json());
const partialId = data.partialId; // keep this
// Later autosaves: reuse partialId -> overwrite in place
await fetch(`${base}/partial`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
data: { your_name: "Ada Lovelace" },
currentPageId: "pg_2",
partialId,
}),
});{ "ok": true, "data": { "partialId": "01J...", "expiresAt": "2026-06-12T00:00:00.000Z" } }If the form does not allow save-and-continue, the call returns 400:
{ "ok": false, "error": "This form doesn't support save-and-continue." }Restore partial state
https://forms.hep.gg/api/v1/forms/public/:slug/partial/:partialIdPublicReturns the answers and the page the submitter was on so you can rehydrate the form. The partialId must belong to the form named by :slug.
slugpartialIddatafield_key.currentPageIdcurl https://forms.hep.gg/api/v1/forms/public/my-form/partial/01J...const r = await fetch(
"https://forms.hep.gg/api/v1/forms/public/my-form/partial/01J...",
);
if (r.status === 410) {
// expired - start fresh
}
const { ok, data } = await r.json();
if (ok) {
// data.data -> answers, data.currentPageId -> resume page
}Errors
| Status | When | error |
|---|---|---|
| 400 | Form does not allow save-and-continue (save only) | This form doesn't support save-and-continue. |
| 404 | Form not found, or partialId does not belong to this form | Form not found / Partial state not found |
| 410 | The saved state is past its 14-day expiry | Partial state has expired |