Sending Projects & Tracking Submissions
Once a project is built and active and at least one integration is connected, you can send its fill link to people and watch every request move from pending to submitted.
What a "send" is
A send creates one request with a single-use fill link, then delivers that link over one or more channels (email, WhatsApp, SMS) to one or more recipients. Everyone reached by the same request shares the same link — the first person to submit completes the request and dead-ends the link for the others. Send separate requests when each person should answer individually.
Sends happen through the External API (POST /api/v1/external/projects/{project_id}/send), authenticated with an API key. You can also share the project's direct link (/fill/<project_id>) manually; submissions through it are tracked too, just without a recipient attached.
Message templates
Templates exist at two levels:
Account defaults — one per channel, edited in Settings → Templates. Every channel ships with a system default message; replace it with your own wording once and every project inherits it.
Project templates — each channel in the project's Templates tab picks one of three sources: Account default (inherit, the default), System default (always send the stock message, even if an account default is set), or Custom (a message just for this project).
Per channel the message carries:
Email — subject + body.
WhatsApp — body only.
Text (SMS) — body only.
Templates support placeholders, replaced at send time:
| Placeholder | Replaced with |
|---|---|
{project} | The project's name |
{link} | The fill link — always include this one |
{name} | Your (the sender's) name |
{company} | Your brand name (falls back to your name) |
{anything_else} | A custom variable supplied in the send request (max 20 per send) |
Built-in placeholders always win over custom variables with the same name. Unknown placeholders are left as-is.
When a send doesn't specify a template, the message resolves in this order: the project's template (a custom message overrides everything; a pinned system default sends the stock message), then the account default from Settings → Templates, then the stock message — a full greeting that opens with Dear {username}, (supply username in the send request's variables; unfilled placeholders go out as-is), names your {company} and {project}, and closes with the {link} and your signature.
Improve — rewrites the template body with better tone/structure (uses the AI backend, like the project builder).
Test send — delivers the current draft to a test recipient through your real integration, so you can check formatting on an actual phone/inbox. You can save test values for your custom placeholders alongside the template.
Request lifecycle
| Status | Meaning |
|---|---|
pending | The link was sent (at least one channel delivered) and nobody has submitted yet |
submitted | Someone opened the link and submitted — the data is stored |
failed | Every delivery attempt failed; the link is dead |
expired | The link's expiry window passed with no submission |
Notes on the mechanics:
Expiry is set per project (Link expiry; empty = never, which is the default). It's evaluated when the link is opened or when statuses are read, counting from the most recent send.
Resend — from the Responses page (or via a new send) you can resend a pending request's link; this restarts the expiry window. Every delivery is appended to the request's send history.
Channel tagging — links are suffixed per channel (
/fill/<id>/email,/fill/<id>/whatsapp,/fill/<id>/text), so a submission records which channel the recipient actually used.
The Responses page
The project's Responses page lists every request and submission (newest first, up to 200 rows), with status badges, channel, recipient, and timestamps. Click a row to see:
Submitted data — every field value the recipient entered.
Delivery history — each send: channel, recipient, the rendered subject/body, and when it went out.
Analytics — captured server-side and from the fill page: IP address, timezone, screen size, and time-to-submit.
Pending rows show their live fill link so you can copy or resend it.
Reacting to submissions
Two push/pull options, usable together:
Webhooks — set a webhook URL on the project and every submission is POSTed to it as it happens.
Status polling —
GET /api/v1/external/requests?ids=...returns each request's status and, once submitted, the response data.