Formwork
Menu
Get started free Log in

Forms and responses endpoints

List and read forms, close or reopen one, page through responses since your last run, and delete a response, with curl examples and the shape of every answer type.

All endpoints are under /api/v1 and need a bearer key; see API keys, requests and errors. Endpoints marked write need a write key.

The examples assume:

export FORMWORK_KEY=fwk_0123456789abcdef0123456789abcdef01234567

GET /forms

Forms in the key's workspace, most recently updated first. Trashed forms are not listed.

ParameterMeaning
statusdraft, published, closed or archived
page, per_pagePagination
curl -s "https://formwork.movortech.com/api/v1/forms?status=published&per_page=10" -H "Authorization: Bearer $FORMWORK_KEY"
{
  "data": [
    {
      "id": "hng8zzkl1lpd",
      "title": "Customer feedback",
      "status": "published",
      "slug": "rlli6ig0",
      "url": "https://formwork.movortech.com/f/rlli6ig0",
      "published": true,
      "response_count": 135,
      "response_limit": null,
      "opens_at": null,
      "closes_at": null,
      "created_at": "2026-09-30T03:09:58+00:00",
      "updated_at": "2026-09-30T03:09:58+00:00"
    }
  ],
  "meta": { "page": 1, "per_page": 10, "total": 1 }
}

id is the form's 12-character id, the same one that appears in dashboard URLs. All timestamps are ISO 8601 in UTC.

GET /forms/{id}

One form, in the same shape as above.

PATCH /forms/{id} (write)

Change the form's status or title. Send at least one field.

FieldValues
statuspublished or closed. Only for a form that is already published; publishing itself happens in the builder
title1 to 200 characters. Renames the form in the dashboard; the title respondents see changes when you publish from the builder
curl -s -X PATCH https://formwork.movortech.com/api/v1/forms/hng8zzkl1lpd \
  -H "Authorization: Bearer $FORMWORK_KEY" -H "Content-Type: application/json" \
  -d '{"status":"closed"}'

Returns the updated form. Closing takes effect on the next request to the public link.

GET /forms/{id}/responses

ParameterMeaning
statussubmitted (default) or in_progress (saved drafts)
sinceISO 8601 date or date-time, for example 2026-09-01 or 2026-09-30T09:00:00Z. Keeps responses submitted at or after it (last saved, for drafts). A value without a time zone is read as UTC
page, per_pagePagination

Newest first. To read everything since your last run, remember the newest submitted_at you saw and pass it as since.

curl -s "https://formwork.movortech.com/api/v1/forms/hng8zzkl1lpd/responses?since=2026-09-30T00:00:00Z&per_page=2" \
  -H "Authorization: Bearer $FORMWORK_KEY"
{
  "data": [
    {
      "id": 146,
      "form_id": "hng8zzkl1lpd",
      "status": "submitted",
      "started_at": "2026-09-30T03:13:48+00:00",
      "submitted_at": "2026-09-30T03:17:40+00:00",
      "duration_sec": 232,
      "email": null,
      "score": null,
      "max_score": null,
      "answers": [
        { "question_id": "q_pd65jeri", "title": "How would you rate your experience?", "type": "rating", "value": 4, "text": "4" },
        { "question_id": "q_4u31tx3z", "title": "What should we improve?", "type": "long_text", "value": "Dark mode, please.", "text": "Dark mode, please." }
      ],
      "meta": { "device": "mobile", "browser": "Chrome", "os": "Android", "ref": "newsletter.example.org", "utm": { "source": "partner" } }
    }
  ],
  "meta": { "page": 1, "per_page": 2, "total": 12 }
}

Each answer has the machine-readable value and a human text. Answers are listed in form order; questions the respondent skipped or that logic hid are left out.

The shape of value

value depends on the question type:

Typevalue
short text, long text, email, url, phonestring
date, time"YYYY-MM-DD", "HH:MM"
number, scale, rating, nps, slidernumber
single choice, multiple choice, dropdown, yes/no, ranking{"ids":["o_a1b2c3d4"],"other":null}, ids in ranked order for ranking
grid (single){"r_row":"c_col"}
grid (multiple){"r_row":["c_a","c_b"]}
file, signature[{"id":"…","name":"cv.pdf","size":123}]
address{"line1","line2","city","region","postal","country"}

For choice questions, ids are option ids. The text field gives the labels, which is what most integrations want to display. Uploaded files are not downloadable through the API; download them from the results page.

GET /forms/{id}/responses/{response_id}

One response, in the same shape. A response id from another form is a 404.

curl -s https://formwork.movortech.com/api/v1/forms/hng8zzkl1lpd/responses/146 -H "Authorization: Bearer $FORMWORK_KEY"

DELETE /forms/{id}/responses/{response_id} (write)

Deletes the response, its answers and uploaded files, and lowers the form's response count. It cannot be undone.

curl -s -X DELETE https://formwork.movortech.com/api/v1/forms/hng8zzkl1lpd/responses/146 -H "Authorization: Bearer $FORMWORK_KEY"
# {"data":{"id":146,"deleted":true}}

Polling pattern

If you cannot receive webhooks, poll on a schedule: request responses with since set to the newest submitted_at from the previous run, and page through the results until the list is shorter than per_page. Keep to well under 120 requests a minute. Because since is "at or after", the last response you saw comes back again, so deduplicate on the response id.

For push instead of pull, use Webhooks.

Updated Sep 30, 2026