Form Response API
The Form Response API allows you to retrieve an individual form response programmatically in JSON format or as a PDF document.
The API returns the same information you can get with a webhook.
The Form Response API
To look up a form response 1, insert its Reference Number into the URL below and submit a GET request:
| API Endpoint | ||
|---|---|---|
https://formsmarts.com/api/v1/entries/Ref_Number | ||
| HTTP Method | ||
| GET | ||
| Parameter | Description | Notes |
| structure | Set to true to include the form structure (list of input fields with their name, ID and data type) and metadata (form ID) in the API response. | Optional, true or false, defaults to false. |
| presigned_urls | Set to true to include pre-signed URLs in the API response so you can automatically retrieve the form uploads and eSignatures associated with the form submission. Pre-signed URLs are only valid for a few minutes. | Optional, true or false, defaults to false. |
| tags | Set to true to include the tags and system tags of the form response in the API response, saving an extra API request. | Optional, true or false, defaults to false. |
| timezone | Timezone used for dates in the API response, for example America/Los_Angeles. Timezones are listed here. | Optional. If missing, we use the timezone of your account or UTC if no timezone is set. |
API Response
If the request is successful, the API returns an HTTP 200 status and a JSON object with the form entry.
- If the structure parameter is true, the API response has a form (form metadata) and a fields attribute
- The form response is accessible at
api_response["entries"][0]. This is for consistency with APIs returning multiple form submissions. - If the form entry has a form context value, it is included in
api_response["entries"][0]["context"]["value"] - If the form submission involved a payment, the amount, currency, processor name and transaction ID of the payment are available in a
api_response["entries"][0]["payment"]object, for example:{'amount': '380.00', 'currency': 'USD', 'processor_name': 'paypal', 'transaction_id': '4XW287768B821925'} - If the tags parameter is true, the tags and system tags of the form response are returned as two lists in the entry's metadata:
api_response["entries"][0]["metadata"]["user_tags"]andapi_response["entries"][0]["metadata"]["system_tags"] - As shown below, the value of upload and signature fields are JSON object. All other values are scalars.
Example
This is the API response for this form demo:
{
"form": {
"id": "lqh"
},
"fields": [
{
"name": "Full Name",
"id": 122619,
"type": "name"
},
{
"name": "Email",
"id": 122620,
"type": "email"
},
{
"name": "Upload Your Picture",
"id": 122621,
"type": "upload"
},
{
"name": "Comments",
"id": 123744,
"type": "text"
}
],
"entries": [
{
"entry": [
"Jane Doe",
"jane@example.com",
{
"type": "upload",
"attachment_id": "f8ud",
"filename": "Capture.PNG",
"presigned_url": "..."
},
"Hello, this is the picture for the project."
],
"metadata": {
"reference_number": "A3PG3EUJV27KZXJHC5TNK2CQI",
"date_submitted": "2022-04-25T02:20:53-07:00",
"ip_address": "1.1.1.1",
"user_tags": ["reviewed"],
"system_tags": ["api submitted"]
}
}
]
}
The user_tags and system_tags metadata items above are only returned if the request has tags=true.
If the request fails, the API returns a non-success HTTP status with a JSON object specifying the error.
Authentication
FormSmarts verifies API requests with a JWT token in the Authorization header. You can sign requests with the FormSmarts API & Webhook Client or a JWT library in your favorite programming language. You'll need to know your FormSmarts Account ID and secret FormSmarts API Key.
You'll find your Account ID in the Account Overview section of your account and your API Key in the Security Settings.
Python Example
The easiest way to use the Form Response API is with the API & Webhook Client, which provides a Python interface to FormSmarts services. Install it with pip:
pip install formsmarts The example below retrieves a form response and downloads the picture uploaded on the form. Credentials are read from environment variables — never hard-code them in your source.
import os
from formsmarts import APIAuthenticator, FormEntry, APIRequestError
auth = APIAuthenticator(os.environ['FS_ACCOUNT_ID'], os.environ['FS_API_KEY'])
def get_form_entry(ref_num):
try:
entry = FormEntry.fetch(auth, ref_num, form_id='lqh', return_tags=True)
except APIRequestError as err:
print(f'Error {err.status}: {err}')
return
print(entry.fields_by_name('Full Name')[0].value) # 'Jane Doe'
print(entry.fields_by_type('email')[0].value) # 'jane@example.com'
print(entry.fields[3].value) # 'Hello, this is the picture for the project.'
print(entry.submitted_at) # A datetime.datetime object
print(entry.tags, entry.system_tags) # ['reviewed'] ['api submitted']
pic = entry.field_by_id(122621)
print(pic.filename) # 'Capture.PNG'
# Download the picture
pic.download(os.path.join('/Users/test/Downloads', pic.filename))
get_form_entry('A3PG3EUJV27KZXJHC5TNK2CQI')
form_idis optional. Passing it allows the client to reuse the structure of the form it has already retrieved, saving a round-trip to the API.return_tags=Truereturns the tags and system tags of the form response with the entry, so readingentry.tagsandentry.system_tagsdoesn't require an extra API request.
Node.js Example
There is a code example showing how to annotate a form response with Node.js in the Notes section. The Form Submission API has another example.
The Form Responses Batch API
The Form Responses Batch API returns several form responses of the same form in a single request 1. Use it when you already know the Reference Numbers of the entries you need, for example after a Search API request.
Insert the form's ID into the URL below and submit a POST request with a JSON body:
| API Endpoint | ||
|---|---|---|
https://formsmarts.com/api/v1/forms/Form_ID/entries/batch | ||
| HTTP Method | ||
POST (application/json) | ||
| Parameter | Description | Notes |
| reference_numbers | A JSON array with the Reference Numbers of the form responses to retrieve. All the entries must belong to the form specified in the URL. | Required, between 1 and 250 Reference Numbers, without duplicates. |
| structure | Set to true to include the form structure (list of input fields with their name, ID and data type) in the API response. | Optional, true or false, defaults to false. |
| tags | Set to true to include the tags and system tags of each form response in the API response. | Optional, true or false, defaults to false. |
| timezone | Timezone used for dates in the API response, for example America/Los_Angeles. | Optional. If missing, we use the timezone of your account or UTC if no timezone is set. |
The endpoint also accepts GET requests taking the same parameters in the query string, with reference_numbers as a comma-separated list. Use POST when retrieving a large number of entries, as the length of a query string is limited.
The response has the same format as the Form Responses by Dates API: a list of entries in api_response["entries"], and a fields attribute if structure is true. The response has no form attribute and entries have no ip_address metadata item.
Code Example
refs = ['A3PG3EUJV27KZXJHC5TNK2CQI', '1WWTZYYKM4ZSHYS5CZZC6BIED']
for entry in FormEntry.fetch_batch(auth, 'lqh', refs, return_tags=True):
print(entry.reference_number, entry.submitted_at, entry.tags)
The Form Response PDF API
The Form Response PDF API allows you to export a form submission as a PDF document. The PDF generated is the same as the one you can get online and via the Download PDF link in email notifications.
To export up a form response as a PDF document 1, insert its Reference Number into the URL below and submit a GET request:
| API Endpoint | ||
|---|---|---|
https://formsmarts.com/api/v1/entries/Ref_Number.pdf | ||
| HTTP Method | ||
| GET | ||
| Parameter | Description | Notes |
| timezone | Timezone used for dates in the API response, for example America/Los_Angeles. Timezones are listed here. | Optional. If missing, we use the timezone of your account or UTC if no timezone is set. |
Code Example
Continuing the code example above, we add a function to download a form response as a PDF document.
def get_pdf(ref_num):
path = os.path.join('/Users/test/Downloads', f'{ref_num}.pdf')
try:
FormEntry.download_pdf(auth, ref_num, path, timezone='America/Los_Angeles')
except APIRequestError as err:
print(f'Error {err.status}: {err}')
The Tag API
The Tag API allows you to list, add and remove the tags of a form response 1, for example to record the status of an entry once it has been processed by your application.
Insert the Reference Number of the form response into the URL below and submit a GET, POST or DELETE request:
| API Endpoint | ||
|---|---|---|
https://formsmarts.com/api/v1/entries/Ref_Number/tags | ||
| HTTP Method | ||
| GET, POST or DELETE | ||
| Method | Description | Parameters |
| GET | Returns the tags of the form response in a user_tags list, its system tags in a system_tags list, and other tags used in your account in a suggested_tags list, most used first. | None. |
| POST | Adds one or more tags to the form response. Tags the entry already has are ignored. | tags: required, a comma-separated list of up to 10 tags. |
| DELETE | Removes a tag from the form response. | tag: required, the tag to remove. |
- A tag has between 1 and 50 characters, which may be letters, digits, spaces and the following characters:
_ $ ' & : - - A form response may have up to 50 tags. A request that would exceed this limit returns an HTTP 403 status.
- System tags are added by FormSmarts and can't be added or removed with the API.
If the request is successful, the API returns an HTTP 200 status. If some tags are invalid, it returns an HTTP 400 status with the invalid tags listed in the params attribute of the JSON response.
Code Example
Continuing the code example above, we mark a form response as processed.
def mark_processed(ref_num):
entry = FormEntry.fetch(auth, ref_num, return_tags=True)
if 'pending' in entry.tags:
entry.remove_tag('pending')
entry.add_tags(['processed', 'invoiced'])
print(entry.tags) # ['reviewed', 'processed', 'invoiced']
The Note API
The Note API allows you to list, add, edit and delete the notes of a form response 1, for example to record what your application did with an entry. Notes added with the API are shown with the form response, alongside those written by you and your users.
Insert the Reference Number of the form response or the ID of a note into the URLs below:
| API Endpoints | ||
|---|---|---|
https://formsmarts.com/api/v1/entries/Ref_Number/notes (GET, POST)https://formsmarts.com/api/v1/notes/ Note_ID (GET, PUT, DELETE) | ||
| Method | Description | Parameters |
| GET /entries/ Ref_Number/notes | Returns a list of the notes of the form response, newest first. | fields: optional, a comma-separated list of the note attributes to return (see below). limit: optional, the maximum number of notes to return, up to 50, defaults to 30. offset: optional, the number of notes to skip, up to 300, defaults to 0. |
| POST /entries/ Ref_Number/notes | Adds a note to the form response. Returns the note_id and date_created of the new note. | note: required, the text of the note, up to 400 characters. |
| GET /notes/ Note_ID | Returns a note. | fields: optional, as above. |
| PUT /notes/ Note_ID | Replaces the text of a note added with the API. | note: required, the new text of the note, up to 400 characters. |
| DELETE /notes/ Note_ID | Permanently deletes a note added with the API. | None. |
A note has the following attributes. All are returned unless the request has a fields parameter listing the attributes you need.
| Attribute | Description |
|---|---|
| note_id | The ID of the note. |
| note | The text of the note. |
| author | The name of the user who wrote the note, your account name for notes you wrote, or API for notes added with the API. |
| author_id | The ID of the user who wrote the note, or your account number (your Account ID without the FSA- prefix) for notes you wrote or added with the API. |
| author_group | user for notes written by a user, admin for notes you wrote or added with the API. |
| date_created | The date the note was added, in the timezone of your account. |
| date_modified | The date the note was last edited, or null if it has never been edited. |
| can_modify | true if you can edit the note with the API. |
| can_delete | true if you can delete the note with the API. |
| friendly_date | The age of the note in words, for example 2 hours ago. |
| is_from_api | true if the note was added with the API. |
| reference_number | The Reference Number of the form response. |
- The API can only edit and delete notes added with the API. Notes written by you or your users can only be edited or deleted online.
- A request to edit or delete a note the API isn't allowed to change returns an HTTP 403 status.
If the request is successful, the API returns an HTTP 200 status. If it fails, it returns a non-success HTTP status with a JSON object specifying the error.
Node.js Example
This example uses the Node.js API Authenticator with an HTTP library. It records that a form response was exported to a CRM, updating the note it added the previous time rather than adding a new one.
const axios = require('axios');
const FormSmartsAPI = require('./formsmarts_api.js');
const API_URL = 'https://formsmarts.com/api/v1';
const NOTE_PREFIX = 'CRM export:';
const au = new FormSmartsAPI.APIAuthenticator(process.env.FS_ACCOUNT_ID, process.env.FS_API_KEY);
const headers = () => ({[FormSmartsAPI.APIAuthenticator.AUTH_HEADER]: au.getAuthorizationHeader()});
async function recordExport(refNum, contactId) {
const text = new URLSearchParams({note: `${NOTE_PREFIX} contact ${contactId}`});
const {data: notes} = await axios.get(`${API_URL}/entries/${refNum}/notes`, {
headers: headers(),
params: {fields: 'note_id,note,is_from_api'},
});
const previous = notes.find(n => n.is_from_api && n.note.startsWith(NOTE_PREFIX));
if (previous) {
await axios.put(`${API_URL}/notes/${previous.note_id}`, text, {headers: headers()});
} else {
const {data} = await axios.post(`${API_URL}/entries/${refNum}/notes`, text, {headers: headers()});
console.log(`Note ${data.note_id} added on ${data.date_created}`);
}
}
recordExport('A3PG3EUJV27KZXJHC5TNK2CQI', '0035f00000XyZ').catch(
err => console.log(`Error ${err.response?.status}: ${err.response?.data?.message ?? err}`)
);
- Not available with Business Starter and Plus accounts.