This guide will walk you through how to programmatically submit a Zefort form.
Normally, users would open a link to fill forms themselves. Sometimes, it can be useful to prefill some parts of the form, and have the user only fill in the missing parts. This guide help you do this programmatically.
As the starting point, you'll need the form ID. You can find it, for example,
in the link to the published form, or in the URL bar when you have opened the
public form webpage. In this example, our form ID is form_1KhE2OL2E6cjXnGb09
.
With the form ID, fetch the form object via the API using a GET request to the
activeforms
endpoint:
import requests
form_id = "form_1KhE2OL2E6cjXnGb09"
response = requests.get(f"https://sandbox.zefort.com/api/activeforms/{form_id}/?expand=__all__")
print(response.json())
form_id=form_1KhE2OL2E6cjXnGb09
curl -X GET "https://sandbox.zefort.com/api/activeforms/$form_id/?expand=__all__"
Sidenote: the expand
argument inlines all available fields to their
full values. Without it, you would need to use multiple separate API
calls to fetch all the needed parts.
The response will have a lot of content and instructions on what the form should look like when rendered. Since we're only interested in submitting the form, not rendering it, most of this can be ignored.
What we really need are IDs for the form fields we must submit.
Here are the relevant parts of the above GET
request response:
{
"display_name": "Form demo",
"formversion": "fv_1K262dynLMb5F2rnCn",
"pages": [
{
"id": "fp_1Ki39SsN4zTeioYwsD",
"type": "questions",
"blocks": [
{
"id": "fb_1JpZhNvpUxtGNhthha",
"block_type": {
"type": "email",
"subtype": "email_address",
"read_only": false
},
"label": {
"en-us": "E-mail address"
},
"required": true
},
{
"id": "fb_1JgjUUOxXvi37ncdN2",
"block_type": {
"type": "input",
"subtype": "full_name",
"read_only": false
},
"label": {
"en-us": "Full name"
},
"required": true
}
]
}
]
}
From the pages
list, you need to find all pages where type
is "questions"
. Usually
there is exactly one such page. Pages contain a list of “blocks”, which are elements of
the form.
To submit the above form as a draft, make a POST
request to the submissions endpoint:
import requests
response = requests.post(
f"https://sandbox.zefort.com/api/activeforms/{form_id}/submissions/",
json={
"formversion": "fv_1K262dynLMb5F2rnCn",
"values": {
"fb_1JpZhNvpUxtGNhthha": "jane@example.com",
"fb_1Ki9crICDr2S5L5EE1": "Jane Doe",
},
"draft": True,
},
)
print(response.json())
form_id="form_1KhE2OL2E6cjXnGb09"
curl -X POST "https://sandbox.zefort.com/api/activeforms/$form_id/submissions/" \
-H "Content-Type: application/json" \
-d '{"formversion": "fv_1K262dynLMb5F2rnCn", "values": {"fb_1JpZhNvpUxtGNhthha": "jane@example.com", "fb_1Ki9crICDr2S5L5EE1": "Jane Doe"}, "draft": true}'
The response includes information about the form submission, along with a form submission ID and a secret token:
{
"draft": true,
"form": "form_1KhE2OL2E6cjXnGb09",
"id": "fsub_1JyYhNMsRmuaRoVE0I",
"token": "secret-token-here",
...
}
You can use this information to submit further edits to the draft or finish the draft
(by setting draft
to false
). The token
value must be sent in the x-zefort-token
header.
If you need to upload one or more files to a draft, you must send a POST
request
with the multipart/form-data
content type, instead of application/json
like above.
Pass a JSON string for values
. Here is what the above form submission would look
like when we add a file upload:
import json
import requests
form_id = "form_1KhE2OL2E6cjXnGb09"
values = {"fb_1JpZhNvpUxtGNhthha": "jane@example.com", "fb_1Ki9crICDr2S5L5EE1": "Jane Doe"}
response = requests.post(
f"https://sandbox.zefort.com/api/activeforms/{form_id}/submissions/",
data={
"formversion": "fv_1K262dynLMb5F2rnCn",
"values": json.dumps(values),
"draft": "true"
},
files={
"fb_1KdNFo9mWk9cMUPK99": (
"myfile.pdf", open("myfile.pdf", "rb"), "application/pdf"
)
}
)
print(response.json())
form_id="form_1KhE2OL2E6cjXnGb09"
curl -X POST "https://sandbox.zefort.com/api/activeforms/$form_id/submissions/" \
-F "formversion=fv_1K262dynLMb5F2rnCn" \
-F "values={\"fb_1JpZhNvpUxtGNhthha\": \"jane@example.com\", \"fb_1Ki9crICDr2S5L5EE1\": \"Jane Doe\"}" \
-F "draft=true" \
-F "fb_1KdNFo9mWk9cMUPK99=@myfile.pdf;type=application/pdf"
You can also have Zefort send an email invitation for someone to finish the form.
import requests
form_id = "form_1KhE2OL2E6cjXnGb09"
form_submission_id = "fsub_1JyYhNMsRmuaRoVE0I"
token = "secret-token-here"
response = requests.post(f"https://sandbox.zefort.com/api/activeforms/{form_id}/submissions/{form_submission_id}/share/",
headers={"x-zefort-token": token},
json={
"email": "john@example.com",
"message": "Hi John, please finish and submit this form. Best, Jane",
})
print(response.json())
form_id="form_1KhE2OL2E6cjXnGb09"
form_submission_id="fsub_1JyYhNMsRmuaRoVE0I"
token="secret-token-here"
curl -X POST "https://sandbox.zefort.com/api/activeforms/$form_id/submissions/$form_submission_id/share/" \
-H "Content-Type: application/json" \
-H "X-Zefort-Token: $token" \
-d '{"email": "john@example.com", "message": "Hi John, please finish and submit this form. Best, Jane"}'