Prefilled Requests
A prefilled request is a unique link to a form that already has data filled in. Use it to save the respondent from re-typing what you already know, or to lock fields so they can't be changed.
- Request Signers — attach the actual signers to the request up front.
- Reminders — automatically remind the primary signer until they complete the form.
Work in progress. Request signers and reminders are still being built and may change.
How it works
- You create a request with
POST /v2/forms/{formId}/requests, providing field values grouped by section. - Collect returns a unique request URL.
- The respondent opens the URL and sees the form with your values already filled in.
- The respondent submits. Each prefilled field is either locked or editable (see below).
- You retrieve the answers using the
requestId.
The editable property
editable propertyEach prefilled field carries an editable flag:
editable | Behaviour |
|---|---|
false (default) | Locked. The respondent sees the value but can't change it. Submitting a different value is rejected. |
true | Pre-populated but changeable. The respondent can overwrite the value before submitting. |
Use false for values that must not change, like a contract ID or national ID. Use true for values the respondent might need to fix, like an email address.
Create a prefilled request
POST /v2/forms/{formId}/requestsRequirements
- The form must exist and be ACTIVE.
- Top-level keys in
answersmust be sectionslugs that exist on the form (a slug is a section's short URL-safe identifier, auto-generated from its title unless you set it explicitly). - Each section value is an array of instance objects: at most one for a normal section, up to
multipleEntries.maxfor a multi-entry section. - Inside each instance, every key must be a writable field that belongs to that section.
- Values must match the field's data type.
Path parameters
| Parameter | Type | Description |
|---|---|---|
formId | UUID | The externalId of the form. |
Request body
{
"answers": {
"<sectionSlug>": [
{ "<fieldName>": { "value": "<fieldValue>", "editable": true } }
]
}
}| Property | Type | Required | Description |
|---|---|---|---|
answers | object | yes | Map keyed by section slug. |
answers.<sectionSlug> | array | yes | Instances to prefill. Normal sections take at most one; multi-entry up to multipleEntries.max. |
answers.<sectionSlug>[i].<fieldName>.value | any | yes | The value. Type must match the field (see Field value formats). |
answers.<sectionSlug>[i].<fieldName>.editable | boolean | no | Whether the respondent can change it. Defaults to false. |
You can also attach signers and reminders in the same call.
Response
{
"requestId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"submissionId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"requestUrl": "https://collect.penneo.com/form/..."
}| Property | Type | Description |
|---|---|---|
requestId | UUID | The request's ID. Use it to retrieve answers later. |
submissionId | UUID | The underlying submission's ID. |
requestUrl | string | The public URL to share with the respondent. |
Errors
| Status | When |
|---|---|
400 Bad Request | Unknown section slug, a field under the wrong section, a normal section with more than one instance, value type mismatch, validation failure, or a non-writable field (e.g. HTML). |
404 Not Found | The form doesn't exist or isn't ACTIVE. |
Field value formats
| Field type | Value format | Example |
|---|---|---|
TEXT | String | "John Doe" |
NUMBER | Number | 42 |
DATE | String YYYY-MM-DD | "1990-01-15" |
DATETIME | String YYYY-MM-DDTHH:mm:ss | "1990-01-15T09:00:00" |
EMAIL | String | "[email protected]" |
PHONE | String (E.164) | "+4512345678" |
NIN | Object { value, countryCode } | { "value": "1234567890", "countryCode": "DK" } |
BUSINESS_ID | Object { value, countryCode } | { "value": "12345678", "countryCode": "DK" } |
CHOICE | Array of option values | ["option_a", "option_b"] |
HTMLandFILEfields cannot be prefilled.
Example
An onboarding form with a personal section and a multi-entry family section:
POST /v2/forms/a1b2c3d4-e5f6-7890-abcd-ef1234567890/requests
Authorization: Bearer <your_api_token>
Content-Type: application/json
{
"answers": {
"personal": [
{
"full_name": { "value": "Jane Smith", "editable": false },
"email": { "value": "[email protected]", "editable": true },
"date_of_birth": { "value": "1985-06-20", "editable": false },
"department": { "value": ["engineering"], "editable": true }
}
],
"family": [
{ "name": { "value": "Ada Lovelace", "editable": true } },
{ "name": { "value": "Charles Babbage", "editable": true } }
]
}
}When Jane opens the returned requestUrl she sees her full name and date of birth locked, her email and department prefilled but editable, and two family members she can edit, remove, or add to.
Updated 4 days ago
