Gladly + Formspree: Customer Care Forms for High-Touch Brands
Structured intake forms put the order number, item, reason, and preferred resolution in front of your Gladly agents from the first message, so they can act on the first read.
Your support inbox gets a message: “Hi, I’d like to return an order.” The customer’s name, email, and nothing else.
Your agent opens the conversation in Gladly, sees the customer’s full purchase history and previous contacts, and sends back: “Of course, could you share your order number and the item you’d like to return?” The customer replies. The agent asks what’s wrong with it. The customer replies again. By the third exchange, the agent finally has enough to act.
Gladly is already doing its job. It surfaces the customer’s timeline, channel preferences, and any agent notes the moment the conversation opens. The problem is the incoming message. “I’d like to return an order” gives Gladly nothing to thread into a resolution. The agent fills in the gaps manually, one question at a time.
A well-designed intake form changes what that first message contains. The customer submits their order number, the item, the reason, and their preferred resolution. That structured data is what the agent sees first in Gladly: the opening message of a conversation if you send submissions by email, or the body of a task if you use the Formspree Gladly plugin. Either way, the agent reads it once and acts.
What to put on a support form
The fields you choose determine whether an agent can act on the first read or has to send follow-up questions. The right fields differ by use case, so a single generic contact form used for every request type costs your team time on every submission.
Four form types cover most high-touch support scenarios, each with different information needs:
- A refund request form needs: order number, item name, reason for return (a select with options like “damaged on arrival,” “wrong item sent,” “changed my mind,” “size issue”), resolution preference (refund, exchange, or store credit), and whether the customer needs a prepaid return label.
- An order inquiry form needs: order number, issue type (not received, damaged in transit, or incorrect item), and a text area for details. Keeping the issue type as a select prevents agents from parsing free-text descriptions before they can route or act.
- A personal shopping request needs: size range, budget, occasion, style notes, and preferred contact method.
- A warranty or repair claim needs: product name, purchase date, description of the defect, and a file upload option for a photo of the damage. File uploads need
enctype="multipart/form-data"on the form tag plus a file input, and are available on the Personal, Professional, and Business plans.
Conditional field logic cuts friction without sacrificing context. A customer reporting a wrong item sent doesn’t need to see “preferred return method.” That field only makes sense for a return. JavaScript-based conditional display means the form surfaces exactly what’s needed for each issue type. A few lines are enough to show a return-method field only when the reason calls for it:
<label id="return-method-field" hidden>
Preferred return method
<select name="return_method">
<option value="Prepaid label">Prepaid label</option>
<option value="Drop-off">Drop-off</option>
</select>
</label>
<script>
const reason = document.querySelector('[name="return_reason"]');
const field = document.getElementById('return-method-field');
const select = field.querySelector('select');
function update() {
field.hidden = reason.value === 'Wrong item sent' || reason.value === '';
select.disabled = field.hidden;
}
reason.addEventListener('change', update);
update();
</script>
Disabling the select when its label is hidden matters. A field that is only hidden still submits its default value, so the agent would see a return method for a customer who never saw the question.
Formspree’s library of order forms has more layouts to start from.
The field names you use in HTML become the labels in what the agent reads in Gladly. order_number is clear. field2 is not. Name fields the way you’d want to see them in an inbox.
Keep required fields to what you actually need to take action. A form that blocks submission unless the customer uploads proof of purchase before they can report a missing delivery pushes customers toward a channel with less structure and less useful context for your team.
Building a return form with Formspree
A return request form is a good starting point because it covers the most common high-touch support scenario and includes enough field types to show how the setup works.
<form action="https://formspree.io/f/YOUR_FORM_ID" method="POST">
<input type="hidden" name="subject" value="Return request: {{ return_reason }}" />
<input type="text" name="_gotcha" style="display:none" />
<label>
Email address
<input type="email" name="email" required />
</label>
<label>
Order number
<input type="text" name="order_number" required />
</label>
<label>
Item name
<input type="text" name="item_name" required />
</label>
<label>
Reason for return
<select name="return_reason" required>
<option value="">Select a reason</option>
<option value="Damaged on arrival">Damaged on arrival</option>
<option value="Wrong item sent">Wrong item sent</option>
<option value="Changed my mind">Changed my mind</option>
<option value="Size issue">Size issue</option>
</select>
</label>
<label>
Preferred resolution
<select name="resolution_preference">
<option value="Refund">Refund</option>
<option value="Exchange">Exchange</option>
<option value="Store credit">Store credit</option>
</select>
</label>
<label>
Do you need a prepaid return label?
<select name="needs_return_label">
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</label>
<label>
Additional notes (optional)
<textarea name="message" rows="4"></textarea>
</label>
<button type="submit">Submit return request</button>
</form>
Replace YOUR_FORM_ID with the ID from your Formspree dashboard before deploying. The notes textarea is named message on purpose: the Formspree Gladly plugin, covered below, requires both an email field and a message field.
The hidden subject field uses Formspree’s template syntax: {{ return_reason }} gets replaced with the customer’s actual selection at submission time. The result becomes the subject of the notification email Formspree sends, so on the email path below the message reaches Gladly as “Return request: Size issue” rather than a generic subject.
The _gotcha honeypot field is hidden from human visitors but gets filled by bots that auto-fill every input they find. Formspree checks it server-side and discards any submission where it’s populated. Formspree’s Formshield spam filter, a machine learning model, also screens submissions, and on the Professional and Business plans you can tune how aggressive it is.
For a React app, the @formspree/react library handles the same form without any changes on the Formspree side:
import { useForm, ValidationError } from '@formspree/react';
export function ReturnForm() {
const [state, handleSubmit] = useForm('YOUR_FORM_ID');
if (state.succeeded) {
return <p>"Your return request has been received. We'll be in touch shortly."</p>;
}
return (
<form onSubmit={handleSubmit}>
<input type="hidden" name="subject" value="Return request: {{ return_reason }}" />
<input type="text" name="_gotcha" style={{ display: 'none' }} />
<label htmlFor="email">Email address</label>
<input id="email" type="email" name="email" required />
<ValidationError field="email" prefix="Email" errors={state.errors} />
<label htmlFor="order_number">Order number</label>
<input id="order_number" type="text" name="order_number" required />
<label htmlFor="item_name">Item name</label>
<input id="item_name" type="text" name="item_name" required />
<label htmlFor="return_reason">Reason for return</label>
<select id="return_reason" name="return_reason" required>
<option value="">Select a reason</option>
<option value="Damaged on arrival">Damaged on arrival</option>
<option value="Wrong item sent">Wrong item sent</option>
<option value="Changed my mind">Changed my mind</option>
<option value="Size issue">Size issue</option>
</select>
<label htmlFor="resolution_preference">Preferred resolution</label>
<select id="resolution_preference" name="resolution_preference">
<option value="Refund">Refund</option>
<option value="Exchange">Exchange</option>
<option value="Store credit">Store credit</option>
</select>
<label htmlFor="needs_return_label">Do you need a prepaid return label?</label>
<select id="needs_return_label" name="needs_return_label">
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
<label htmlFor="message">Additional notes (optional)</label>
<textarea id="message" name="message" rows={4} />
<button type="submit" disabled={state.submitting}>
{state.submitting ? 'Submitting...' : 'Submit return request'}
</button>
<ValidationError errors={state.errors} />
</form>
);
}
Formspree fills in the subject template when it receives the submission, using the field values the form sends, so the hidden subject field behaves the same in React as in plain HTML. The disabled state on the submit button during state.submitting prevents duplicate submissions from impatient clicks.
Getting form submissions into Gladly
Three paths connect your forms to Gladly via Formspree, ranging from zero configuration to a custom serverless function. They don’t produce the same thing in Gladly. The email path opens a conversation, the customer-facing thread. The plugin creates a task on the customer’s timeline for your team to act on. Plans differ too: the Gladly plugin and webhooks are available on the Professional and Business plans, while the email path uses neither.
The email path
The simplest option needs no API credentials and doesn’t use the Gladly plugin. Formspree sends submission notifications to your form’s target email, and Gladly’s email channel opens a conversation for each email that arrives at an email entry point. The form data becomes the opening message of that conversation.
To set this up, add your Gladly email entry point (support@yourbrand.com or equivalent) as a linked email under the Account tab by clicking + Add Email, and verify it. Then select it as the target email for the form. Gladly expects the email’s reply-to header to be the customer’s address, which is how it knows who the message is from. Formspree sets Reply-To from your form’s email field, so keep an input with that name. The subject line templating from the form (Return request: {{ return_reason }}) sets the subject of the email Formspree sends to Gladly.
Field data arrives as plain text in the email body rather than as structured fields, and Formspree has no visibility into whether the receiving mail server accepts the message. For low-volume forms where neither constraint matters, this works. For anything beyond that, the plugin is the better call.
The Formspree Gladly plugin (recommended)
The Formspree Gladly plugin connects directly to the Gladly API. It’s available on the Professional and Business plans. Each submission creates a task in Gladly (not a conversation) with the customer looked up or created by their email address, all form fields listed in the task body, and file attachments included as links.
The form needs an input named email and an input named message. To set the plugin up, go to your form’s Workflow tab, select Gladly, and provide your Gladly subdomain, connected email address, and API key. Gladly’s setup guide recommends creating a dedicated Gladly user for the integration, with the Administrator, Agent, and API User roles, and generating the API token from that user. You then pick which Gladly inbox the tasks land in and set a due date for SLA tracking. Gladly highlights overdue tasks automatically so your team can see which requests are aging.
Field naming matters here. Formspree maps a field named message or msg to the main task body, which is why the notes textarea in the return form above is named message. That text becomes the primary content of the Gladly task, and every other field is added to the bottom of it. Formspree uses the email value to find the matching Gladly customer, or to create one if none exists.
The plugin also has a Test Mode that opens tasks in your Gladly staging environment instead of production, useful to verify field mapping before a new form goes live.
The webhook path
If you need to direct different form values to different inboxes at submission time, or enrich the customer profile before the task opens, Formspree can fire a webhook (available on the Professional and Business plans) to a serverless function that calls the Gladly REST API directly. The API has resources for tasks, conversation items, and customers, so the function can decide which one a given submission should create.
Set the webhook URL in your form’s Workflow tab and write a small function to map the Formspree payload to a Gladly task or conversation item. Verify the webhook signature before acting on a request, since anyone can POST to a public URL. You get full control over inbox assignment and customer attribute updates at the cost of maintaining that function.
Routing multiple form types to the right teams
Once you have more than one form type, you need each one to land with the right Gladly team.
With the Formspree Gladly plugin, routing is per-form: each form has its own plugin configuration, and you can select a different Gladly inbox for each one. Returns go to the returns inbox, personal shopping requests go to the personal shopping inbox, warranty claims go to the quality team, all configured in the Formspree dashboard with no code and no email alias setup. A hidden field in each form can record the type in the submission data, and on the Business plan you can also use it in Form Rules:
<input type="hidden" name="form_type" value="return_request" />
With the email path, routing works through the target email. Send each form’s notification to a different address (returns@yourbrand.com, shopping@yourbrand.com, warranty@yourbrand.com), each of which maps to a different Gladly email entry point and inbox. Each address has to be added and verified as a linked email first. To split one form’s submissions across addresses by field value, use Form Rules, available on the Business plan.
What the agent sees
When a return request comes through, the form data is the first thing in front of the agent: the opening message of the conversation on the email path, or the body of the task on the plugin path. The agent sees the order number, the item, the reason for the return, and the preferred resolution, all labeled, in one place, alongside everything Gladly already knows: previous orders, past support contacts, any notes other agents have left.
For a standard size exchange, the agent pulls up the order, confirms the replacement is in stock, and replies with a prepaid return label and a confirmation of the new item shipping, all in the first message. For a personal shopping request, instead of opening with “Can you tell me more about what you’re looking for?” the agent opens with a curated selection, because the form already captured size range, budget, and occasion.
The customer feels known without having explained themselves twice.
Next steps
For more on the native plugin setup, Formspree’s Gladly integration docs cover the full configuration options. For the webhook path, the Gladly REST API reference covers the tasks, conversation items, and customers endpoints, and Formspree’s webhook documentation covers payload structure and retry behavior.
FAQ
Does Formspree integrate with Gladly?
Yes. Formspree has a native Gladly plugin on the Professional and Business plans that creates a Gladly task for every submission. You can also send submissions to a Gladly email entry point, which opens a conversation instead. Gladly’s own documentation lists both methods and notes that the integration is built and maintained by Formspree.
How do I connect a contact form to Gladly?
Build a form that posts to Formspree, then pick a method. For the plugin, open the form’s Workflow tab, select Gladly, and enter your Gladly subdomain, connected email, and API key. Then choose the inbox and an optional due date. For the email method, add your Gladly email entry point as a linked email in your Formspree account, verify it, and select it as the form’s target email.
What fields does the Gladly plugin require?
An input named email and an input named message (or msg). Formspree uses the email value to find the matching Gladly customer, or to create one if none exists, and uses message as the main text of the task. Every other field is added to the bottom of the task, and uploaded files appear as links.
How do I send a form to Gladly by email?
Add the email entry point you configured in Gladly as a linked email under your Formspree account, verify it, and select it as the form’s target email. Gladly expects the reply-to header to be the customer’s email address. Formspree sets Reply-To from the form’s email field, so keep an input with that name. Formspree can’t tell whether the receiving mail server accepts the message, so test the form before you rely on it.
What should a return request form include?
At minimum, the customer’s email, the order number, the item, and the reason for the return. Add the resolution they want (refund, exchange, or store credit) and whether they need a prepaid return label. Make the reason and resolution select inputs rather than free text, so your team can route and act on them without reading a paragraph. Some templates also ask for the purchase date, product code, and amount paid, depending on your return policy.
How do I create a return request form for my online store?
Write a plain HTML form that posts to your Formspree endpoint, with name attributes that read well in an inbox, such as order_number and return_reason. Add a hidden subject field with {{ return_reason }} so each submission arrives with a useful subject, then connect the form to Gladly. The full example above covers both HTML and React, and Formspree’s refund request form template is a starting point if you’d rather begin from a ready-made layout.
Can I connect a web form directly to a helpdesk or ticketing system?
Yes, without building your own backend. A form backend like Formspree receives the submission and passes it on. Native plugins cover tools such as Gladly, Freshdesk, Zendesk, and Gorgias. For anything else, a webhook sends the submission as JSON to a function you write, which can call the helpdesk’s API.
Which Formspree plans include the Gladly plugin?
The Gladly plugin and webhooks are available on the Professional and Business plans. The email method doesn’t use either, so it works without them. Splitting one form’s submissions across several addresses by field value uses Form Rules, which are on the Business plan. See the plans page for current details.