Submissions API

A submission is a single response to one of your Droplet forms, carried through its workflow from first save to final completion. The Submissions API lets you create submissions (one at a time or in bulk), look them up and filter them, move them through their steps, manage assignees and reminders, archive and restore them, and pull the data back out as PDFs or spreadsheets. Reach for it whenever you need to read, drive, or export form responses programmatically.

Submissions API

All requests go to the base URL https://api.droplet.io, and every endpoint requires a bearer token: send Authorization: Bearer <token> on each call. See the Overview article for details on obtaining and refreshing tokens.

Successful responses share a common envelope: { "requestId": "...", "success": true, "data": { ... } }. When something goes wrong, success is false and an error object with code and message takes the place of data. Path parameters are shown with a leading colon, such as :id, which you replace with the real value. Examples show the fields you will most commonly use; a submission may carry more, so ignore any you do not recognize.

A submission's status (such as in_progress, completed, draft, or done) is set by the workflow and is read-only. You move a submission forward by advancing its step (see Updating submissions), not by setting status directly.

Listing and lookup

List submission IDs

GET /v1/submissions/ids

Returns the IDs of submissions matching your filters, along with a total count. This is the workhorse for finding submissions: filter and sort here, then hydrate the IDs you care about with the entities endpoint.

ParameterInTypeRequiredDescription
pagequeryintegerNoZero-based page of results.
showquerystringNoOne of all, archived, active, or voided.
searchquerystringNoFree-text search across submission data.
formIdquerystringNoLimit to one form.
employeeId, employeeIdsquerystring, arrayNoFilter by employee.
versionquerystringNoLimit to one form version.
packetTemplateId, packetId, packetSubjectquerystringNoFilter by packet.
statusquerystringNoWorkflow status.
created, modified, completedquerystringNoDate-range filters.
timezonequerystringNoTimezone applied to date filters.
assignedTo, assignedToEmailquerystringNoFilter by current assignee.
assignedToWhenquerystringNoOne of currently, last7days, last30days, thisYear, all.
submittedBy, submittedByEmailquerystringNoFilter by submitter.
staleTagsquerybooleanNoInclude submissions with stale tags.
tagKey, tagValuequerystringNoFilter by a tag key/value pair.
sortquerystringNoOne of id, lastCreated, lastModified, tagValue, status. Defaults to lastCreated.
sortOrderquerystringNoasc or desc.
sortTagKeyquerystringNoTag key to sort by when sort=tagValue.
curl -G https://api.droplet.io/v1/submissions/ids \
  -H "Authorization: Bearer <token>" \
  --data-urlencode "formId=onboarding-2024" \
  --data-urlencode "show=active" \
  --data-urlencode "sort=lastModified"
{
  "requestId": "req_8fa2",
  "success": true,
  "data": {
    "count": 3,
    "ids": [1042, 1043, 1051]
  }
}

List submission tag keys

GET /v1/submissions/tags

Returns the distinct tag keys present across submissions that match your filters. Handy for building tag-based filter UIs or discovering what metadata is in play.

ParameterInTypeRequiredDescription
showquerystringNoOne of all, archived, active, voided.
search, formId, versionquerystringNoNarrow the set of submissions scanned.
employeeId, employeeIdsquerystring, arrayNoFilter by employee.
packetTemplateId, packetId, packetSubject, statusquerystringNoPacket and status filters.
created, modified, completed, timezonequerystringNoDate-range filters.
assignedTo, assignedToEmail, submittedBy, submittedByEmailquerystringNoPeople filters.
tagKey, tagValuequerystringNoFilter by an existing tag pair.
curl -G https://api.droplet.io/v1/submissions/tags \
  -H "Authorization: Bearer <token>" \
  --data-urlencode "formId=onboarding-2024"
{
  "requestId": "req_2c7d",
  "success": true,
  "data": ["department", "region", "employeeId"]
}

Retrieving submission data

Get a submission by ID

GET /v1/submissions/:id

Fetches a single submission together with the form it belongs to. The response includes the submitted data, assignee state, activity log, tags, and the form definition needed to render it.

ParameterInTypeRequiredDescription
idpathintegerYesThe submission ID.
tokenquerystringNoAccess token for shared or assignee links.
substepIdquerystringNoTarget a specific parallel substep.
curl https://api.droplet.io/v1/submissions/1042 \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a91b",
  "success": true,
  "data": {
    "assetToken": "tok_assets_...",
    "submission": {
      "id": 1042,
      "submittedBy": { "name": "Dana Lee", "email": "dana@acme.com" },
      "created": "2026-05-01T14:22:10Z",
      "modified": "2026-05-02T09:10:00Z",
      "formId": "onboarding-2024",
      "version": "v3",
      "formName": "New Hire Onboarding",
      "status": "in_progress",
      "step": "manager-review",
      "data": { "firstName": "Dana", "startDate": "2026-06-01" },
      "tags": { "department": "Engineering" },
      "progress": { "stepLabel": "Manager Review", "percent": 60 }
      // ...
    },
    "form": {
      "id": "onboarding-2024",
      "name": "New Hire Onboarding",
      "version": { "id": 12, "version": "v3", "locked": true }
      // ...
    }
  }
}

Get multiple submissions

POST /v1/submissions/entities

Resolves a batch of submission IDs into full submission records in one call. Pair it with the IDs endpoint to page through results. metaOnly is required: send false for full records, or true to omit heavy field data when you only need summary info.

ParameterInTypeRequiredDescription
includeProgressquerystringNoPass includeProgress=true to include per-submission progress details.
idsbodyarray of integerYesBetween 1 and 50 submission IDs.
metaOnlybodybooleanYesReturn metadata only, omitting full field data.
curl https://api.droplet.io/v1/submissions/entities \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "ids": [1042, 1043], "metaOnly": false }'
{
  "requestId": "req_77ce",
  "success": true,
  "data": [
    {
      "id": 1042,
      "submittedBy": { "name": "Dana Lee", "email": "dana@acme.com" },
      "formId": "onboarding-2024",
      "status": "in_progress",
      "step": "manager-review",
      "data": { "firstName": "Dana" },
      "tags": { "department": "Engineering" }
      // ...
    }
    // ...
  ]
}

Get a submission's activity log

GET /v1/submissions/:id/activity-log

Returns the chronological activity log for a single submission, including who acted, what step it touched, recipients, and timestamps.

ParameterInTypeRequiredDescription
idpathintegerYesThe submission ID.
curl https://api.droplet.io/v1/submissions/1042/activity-log \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_b034",
  "success": true,
  "data": {
    "id": 1042,
    "activityLog": [
      {
        "type": "submitted",
        "actor": { "name": "Dana Lee", "email": "dana@acme.com" },
        "step": "applicant-info",
        "timestamp": "2026-05-01T14:22:10Z"
      }
      // ...
    ]
  }
}

Creating submissions

Create a submission

POST /v1/submissions

Creates a single submission against a form. Use action to control intent: submit to finalize the current step, save to store progress, or packet to start a packet submission.

ParameterInTypeRequiredDescription
formIdbodystringYesThe form to submit against.
actionbodystringYesOne of submit, save, packet.
databodyobjectYesThe submission field values.
versionbodystringNoSpecific form version.
packetIdbodystringNoPacket to attach the submission to.
submittedBybodyobjectNoSubmitter name and email.
assignedTobodyobjectNoInitial assignee name and email.
savedProgressbodyobjectNoPartial progress to seed the submission.
curl https://api.droplet.io/v1/submissions \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "formId": "onboarding-2024",
    "action": "submit",
    "submittedBy": { "name": "Dana Lee", "email": "dana@acme.com" },
    "data": { "firstName": "Dana", "startDate": "2026-06-01" }
  }'
{
  "requestId": "req_31ab",
  "success": true,
  "data": { "id": 1052 }
}

Create submissions in bulk

POST /v1/submissions/create

Creates many submissions for one form in a single request. Each entry must include submittedByName and submittedByEmail, plus any form field values as additional properties. The response reports which entries succeeded and which failed by index.

ParameterInTypeRequiredDescription
formIdbodystringYesThe form to submit against.
actionbodystringYesMust be submit.
submissionsbodyarrayYes1 to 500 entries, each with submittedByName, submittedByEmail, and field values.
versionbodystringNoSpecific form version.
curl https://api.droplet.io/v1/submissions/create \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "formId": "onboarding-2024",
    "action": "submit",
    "submissions": [
      { "submittedByName": "Dana Lee", "submittedByEmail": "dana@acme.com", "startDate": "2026-06-01" },
      { "submittedByName": "Sam Ortiz", "submittedByEmail": "sam@acme.com", "startDate": "2026-06-08" }
    ]
  }'
{
  "requestId": "req_55de",
  "success": true,
  "data": {
    "success": true,
    "successes": [1053, 1054],
    "errors": []
  }
}

Duplicate a submission

POST /v1/submissions/:id/duplicate

Creates a copy of an existing submission and returns the new record along with its form. Useful for cloning a near-identical response without re-entering data.

ParameterInTypeRequiredDescription
idpathintegerYesThe submission to duplicate.
tokenquerystringNoAccess token for shared links.
curl -X POST https://api.droplet.io/v1/submissions/1042/duplicate \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_9a0c",
  "success": true,
  "data": {
    "submission": {
      "id": 1060,
      "formId": "onboarding-2024",
      "status": "draft",
      "data": { "firstName": "Dana" }
      // ...
    },
    "form": { "id": "onboarding-2024", "version": { "version": "v3" } }
    // ...
  }
}

Updating submissions

Update a submission

PUT /v1/submissions/:id

Saves changes to a submission's data at a given step. Use action to choose what happens: submit advances the step, save stores progress, and reject rejects the current step. The response returns the updated submission and form.

ParameterInTypeRequiredDescription
idpathintegerYesThe submission ID.
actionbodystringYesOne of submit, reject, save.
stepbodystringYesThe step the update applies to.
databodyobjectYesThe updated field values.
submittedBybodyobjectNoSubmitter name and email.
curl -X PUT https://api.droplet.io/v1/submissions/1042 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "submit",
    "step": "manager-review",
    "data": { "approved": true }
  }'
{
  "requestId": "req_4f12",
  "success": true,
  "data": {
    "submission": { "id": 1042, "status": "completed", "step": "done" },
    "form": { "id": "onboarding-2024", "version": { "version": "v3" } }
    // ...
  }
}

Assigning and reminding

Assign multiple submissions

POST /v1/submissions/assign

Assigns a set of submissions to a single person. Provide the target via assignedTo (or assignee), and optionally include a custom notification message.

ParameterInTypeRequiredDescription
idsbodyarray of integerYesSubmission IDs to assign.
assignedTobodyobjectNoAssignee name and email.
assigneebodyobjectNoAlternate assignee field with name and email.
customMessagebodyobjectNoNotification subject and message.
curl https://api.droplet.io/v1/submissions/assign \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": [1042, 1043],
    "assignedTo": { "name": "Pat Kim", "email": "pat@acme.com" }
  }'
{
  "requestId": "req_60aa",
  "success": true,
  "data": { "success": true }
}

Reassign contributors on a submission

POST /v1/submissions/:id/assign

Assigns or reassigns one or more contributors on a single submission. Each key in reassignments maps a role or step to a new assignee.

ParameterInTypeRequiredDescription
idpathintegerYesThe submission ID.
reassignmentsbodyobjectYesMap of target keys to { name, email } assignees.
customMessagebodyobjectNoNotification subject and message.
curl https://api.droplet.io/v1/submissions/1042/assign \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "reassignments": {
      "manager-review": { "name": "Pat Kim", "email": "pat@acme.com" }
    }
  }'
{
  "requestId": "req_71bb",
  "success": true,
  "data": { "success": true }
}

Send reminders

POST /v1/submissions/remind

Sends reminder notifications to the current assignees of the listed submissions. Add a custom message to override the default reminder text.

ParameterInTypeRequiredDescription
idsbodyarray of integerYesSubmission IDs to remind on.
customMessagebodyobjectNoNotification subject and message.
curl https://api.droplet.io/v1/submissions/remind \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "ids": [1042, 1043] }'
{
  "requestId": "req_82cc",
  "success": true,
  "data": { "success": true }
}

Workflow actions

Send a submission back

POST /v1/submissions/send-back

Returns a submission to an earlier step, for example to request corrections. You must identify the step to send back to, a reason, and whether to reset the data captured since then.

ParameterInTypeRequiredDescription
idbodyintegerYesThe submission ID.
reasonbodystringYesWhy the submission is being sent back.
stepIdbodystringYesThe step to return to.
submittedAtbodynumberYesTimestamp of the target step submission.
resetDatabodybooleanYesWhether to clear data captured after the target step.
curl https://api.droplet.io/v1/submissions/send-back \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 1042,
    "reason": "Missing start date",
    "stepId": "applicant-info",
    "submittedAt": 1746108130,
    "resetData": false
  }'
{
  "requestId": "req_93dd",
  "success": true,
  "data": { "success": true, "message": "Submission sent back to Applicant Info" }
}

Set form version

POST /v1/submissions/set-form-version

Moves the listed submissions onto a specific form version. The response returns how many submissions were updated.

ParameterInTypeRequiredDescription
idsbodyarray of integerYesSubmission IDs to update.
versionbodystringYesThe target form version.
curl https://api.droplet.io/v1/submissions/set-form-version \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "ids": [1042, 1043], "version": "v4" }'
{
  "requestId": "req_a4ee",
  "success": true,
  "data": { "count": 2 }
}

Set dataset version

POST /v1/submissions/set-dataset-version

Updates which dataset versions the listed submissions resolve against. Provide one entry per dataset you want to pin. The response returns how many submissions were updated.

ParameterInTypeRequiredDescription
idsbodyarray of integerYesSubmission IDs to update.
updatedVersionsbodyarrayYesEntries of { datasetId, versionId }.
curl https://api.droplet.io/v1/submissions/set-dataset-version \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": [1042],
    "updatedVersions": [ { "datasetId": "locations", "versionId": 7 } ]
  }'
{
  "requestId": "req_b5ff",
  "success": true,
  "data": { "count": 1 }
}

Archiving and restoring

Archive submissions

POST /v1/submissions/archive

Archives the listed submissions, removing them from active views while keeping them recoverable. Returns the number archived.

ParameterInTypeRequiredDescription
idsbodyarray of integerYesSubmission IDs to archive.
curl https://api.droplet.io/v1/submissions/archive \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "ids": [1042, 1043] }'
{
  "requestId": "req_c601",
  "success": true,
  "data": { "count": 2 }
}

Restore submissions

POST /v1/submissions/restore

Restores previously archived submissions back into active status. Returns the number restored.

ParameterInTypeRequiredDescription
idsbodyarray of integerYesSubmission IDs to restore.
curl https://api.droplet.io/v1/submissions/restore \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "ids": [1042] }'
{
  "requestId": "req_d712",
  "success": true,
  "data": { "count": 1 }
}

Export, download, and PDF

The PDF and export endpoints return a serialized file payload in data plus a headers object describing the file (such as content type and disposition). Reconstruct the file on your side using those headers.

Generate a submission PDF

POST /v1/submissions/:id/pdf

Generates a PDF rendering of a single submission. Use options to tune layout and what to include, such as uploads, the activity log, or a data verification key.

ParameterInTypeRequiredDescription
idpathintegerYesThe submission ID.
optionsbodyobjectNoBooleans: compactLayout, reducedMargins, privateUploads, uploadsInPdf, generalInfo, dataVerificationKey, activityLog. All default to false.
curl https://api.droplet.io/v1/submissions/1042/pdf \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "options": { "uploadsInPdf": true, "activityLog": true } }'
{
  "requestId": "req_e823",
  "success": true,
  "data": {
    "data": { "type": "Buffer", "data": [37, 80, 68, 70] },
    "headers": {
      "content-type": "application/pdf",
      "content-disposition": "attachment; filename=\"submission-1042.pdf\""
    }
  }
}

Download submissions

POST /v1/submissions/download

Returns the listed submissions grouped by form, including each form's layout, steps, and datasets alongside its submissions. This is the structured download used to render or archive responses with full context.

ParameterInTypeRequiredDescription
idsbodyarray of integerYesSubmission IDs to download.
curl https://api.droplet.io/v1/submissions/download \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "ids": [1042, 1043] }'
{
  "requestId": "req_f934",
  "success": true,
  "data": {
    "forms": [
      {
        "form": {
          "id": "onboarding-2024",
          "name": "New Hire Onboarding",
          "version": "v3",
          "layout": { /* ... */ },
          "steps": { /* ... */ },
          "datasets": { /* ... */ }
        },
        "submissions": [
          { "id": 1042, "status": "completed", "data": { "firstName": "Dana" } }
          // ...
        ]
      }
    ]
  }
}

Get download settings

GET /v1/submissions/download/settings

Returns the form versions available for a given form so you can offer version choices before downloading.

ParameterInTypeRequiredDescription
formIdquerystringYesThe form to inspect.
curl -G https://api.droplet.io/v1/submissions/download/settings \
  -H "Authorization: Bearer <token>" \
  --data-urlencode "formId=onboarding-2024"
{
  "requestId": "req_0a45",
  "success": true,
  "data": {
    "versions": [
      { "id": "onboarding-2024", "name": "New Hire Onboarding", "version": "v3" }
      // ...
    ]
  }
}

Get export settings

GET /v1/submissions/export/settings

Returns the available columns (headers) and repeating tables for a form, so you can build the column selection that the export endpoint expects.

ParameterInTypeRequiredDescription
formIdquerystringYesThe form to inspect.
curl -G https://api.droplet.io/v1/submissions/export/settings \
  -H "Authorization: Bearer <token>" \
  --data-urlencode "formId=onboarding-2024"
{
  "requestId": "req_1b56",
  "success": true,
  "data": {
    "headers": [
      { "id": "firstName", "label": "First Name" },
      { "id": "startDate", "label": "Start Date" }
    ],
    "tables": [
      {
        "id": "dependents",
        "label": "Dependents",
        "columns": [ { "id": "name", "label": "Name" } ]
      }
    ]
  }
}

Export submissions

POST /v1/submissions/export

Exports the chosen submissions as a spreadsheet file payload in CSV or XLSX. Use the export settings endpoint to discover valid header IDs, then pass them in options.headers.

ParameterInTypeRequiredDescription
formIdbodystringYesThe form being exported.
idsbodyarray of integerYesSubmission IDs to export.
optionsbodyobjectYesExport options (see below).
options.headersbodyarrayYesColumns to include, each with an id and optional label.
options.formatbodystringYescsv or xlsx.
options.singleSheetbodybooleanNoCombine output into one sheet.
options.inlineTablesbodybooleanNoInline repeating-table data.
options.privateUploadLinksbodybooleanNoUse private links for uploads.
options.tableIdbodystringNoExport a specific repeating table.
curl https://api.droplet.io/v1/submissions/export \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "formId": "onboarding-2024",
    "ids": [1042, 1043],
    "options": {
      "headers": [ { "id": "firstName" }, { "id": "startDate" } ],
      "format": "xlsx"
    }
  }'
{
  "requestId": "req_2c67",
  "success": true,
  "data": {
    "data": { "type": "Buffer", "data": [80, 75, 3, 4] },
    "headers": {
      "content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      "content-disposition": "attachment; filename=\"submissions.xlsx\""
    }
  }
}

Address helpers

Get address suggestions

GET /v1/submissions/address-suggestions

Returns address autocomplete suggestions for a partial address, ideal for powering address fields. Pass a stable sessionId to group related keystrokes.

ParameterInTypeRequiredDescription
addressquerystringYesThe partial address to complete.
sessionIdquerystringYesAutocomplete session identifier.
curl -G https://api.droplet.io/v1/submissions/address-suggestions \
  -H "Authorization: Bearer <token>" \
  --data-urlencode "address=1600 Amphi" \
  --data-urlencode "sessionId=sess_abc"
{
  "requestId": "req_3d78",
  "success": true,
  "data": [
    {
      "placeId": "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
      "mainText": "1600 Amphitheatre Parkway",
      "secondaryText": "Mountain View, CA, USA"
    }
  ]
}

Look up distance between addresses

POST /v1/submissions/distance-lookup

Calculates the distance between two addresses, useful for mileage or travel fields. The returned distance is a number you can format as needed.

ParameterInTypeRequiredDescription
startAddressbodystringYesThe origin address.
endAddressbodystringYesThe destination address.
curl https://api.droplet.io/v1/submissions/distance-lookup \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "startAddress": "1600 Amphitheatre Parkway, Mountain View, CA",
    "endAddress": "1 Infinite Loop, Cupertino, CA"
  }'
{
  "requestId": "req_4e89",
  "success": true,
  "data": { "distance": 11.4 }
}

Every endpoint can also return an error envelope with success: false and an error object containing code and message. Check success before reading data.

Last reviewed by Nick Duell and published on June 22, 2026 9PM ET