User Identification
Identify respondents and attach contact traits through shareable feedback links
You can identify a respondent and provide contact traits by adding contact_ query parameters to a shareable feedback link. This is useful for email surveys, customer follow-ups, lifecycle campaigns, and other situations where you already know who will receive the link.
For example:
https://form.encatch.com/<shareable-link-id>?contact_id=customer_123&contact_email=alice%40example.com&contact_display_name=Alice&contact_plan=proThe example identifies the respondent as customer_123 and supplies their email address, display name, and plan.
Contact parameters are not authentication by default
Anyone who can access or modify an unsigned link can change its query parameters. Use optional identity verification when the respondent's identity needs to be trusted.
Parameter format
| Parameter | Purpose |
|---|---|
contact_id | Stable external identifier for the respondent |
contact_email | Respondent's email address and email-only fallback identifier |
contact_<trait-slug> | Contact trait to associate with the respondent |
contact_signature | Optional server-generated HMAC identity signature |
contact_signature_time | Optional signature timestamp in Unix epoch milliseconds |
Parameters are case-sensitive. Use the exact lowercase contact_ prefix.
Choose the contact identifier
For the most reliable cross-channel history, provide contact_id using the same stable identifier that your application uses with identifyUser:
?contact_id=customer_123The identifier must contain 1–50 ASCII characters. Letters, numbers, ., _, @, and - are supported. Spaces, Unicode characters, and other symbols are not supported.
You can identify a respondent using only their email address:
?contact_email=alice%40example.comWhen both parameters are present, contact_id is the identity and contact_email is stored as the email trait:
?contact_id=customer_123&contact_email=alice%40example.comPrefer contact_id when the same person may receive email surveys and use an application where they are identified through the Web or Mobile SDK. Reusing the same identifier keeps their feedback activity associated with one contact.
Add contact traits
Add contact_ before a user-trait slug:
?contact_id=customer_123&contact_display_name=Alice&contact_plan=pro&contact_region=INThis supplies the following traits:
{
"display_name": "Alice",
"plan": "pro",
"region": "IN"
}Trait slugs may contain lowercase letters, numbers, and underscores. URL traits use merge semantics: supplied values set or overwrite the corresponding trait, while traits omitted from the link remain unchanged.
The link cannot perform advanced trait operations such as incrementing, decrementing, removing traits, or replacing the complete contact record.
Projects can control whether previously unknown traits may be created from client data. If automatic trait creation is disabled, only existing enabled traits are accepted. See User Traits.
Values are strings
URL contact values are read as strings. Existing trait configuration may validate or convert an accepted value according to the trait's data type. Numeric-looking identifiers and values are not automatically converted by the URL parser.
Combine identification with response prefilling
contact_ and response_ parameters have separate purposes and can be used in the same link:
https://form.encatch.com/<shareable-link-id>?contact_id=customer_123&contact_plan=pro&response_nps=9contact_idandcontact_plandescribe the respondent.response_npssupplies the initial answer to the NPS question.
Opening the link does not submit the prefilled answer. The respondent can review or change it before submitting. See Advanced Configuration for supported response formats.
When the contact is created or updated
Opening a shareable link performs a read-only contact lookup. It does not create a new contact or update an existing contact merely because the page was loaded.
A contact is created or updated when one of these events occurs:
- The respondent submits the form.
- An eligible partial response is saved after the respondent's effective answers differ from the initialized prefilled answers.
If someone opens the link and leaves without interacting, no contact or response is created. This also prevents ordinary email-link previews and page scans from creating contacts.
Optional identity verification
Unsigned links are supported by default. For cases where the supplied identity must be verified, generate an HMAC signature on your server and add it to the link:
?contact_id=customer_123&contact_signature=<server-generated-signature>Never generate the signature in browser code or expose your secret key in the link. Keep the secret on your server. See Publishable SDK Keys.
When no signature session timeout is configured, sign the identifier:
import crypto from 'node:crypto';
const signature = crypto
.createHmac('sha256', process.env.ENCATCH_SECRET_KEY)
.update('customer_123')
.digest('hex');When a session timeout is configured, include the current Unix epoch time in milliseconds in both the signed value and URL:
import crypto from 'node:crypto';
const contactId = 'customer_123';
const timestamp = String(Date.now());
const signature = crypto
.createHmac('sha256', process.env.ENCATCH_SECRET_KEY)
.update(contactId + timestamp)
.digest('hex');?contact_id=customer_123&contact_signature=<signature>&contact_signature_time=<timestamp>contact_signature_time is optional in the URL format but required when the configured signature policy uses a session timeout. If email is the only identifier, use the email address as the value being signed.
Identity verification verifies the identifier. It does not make other URL parameters secret, and an identity-only signature does not protect arbitrary contact_ or response_ values from modification.
Generate and encode links safely
Use URL and URLSearchParams instead of manually joining query strings:
const link = new URL('https://form.encatch.com/<shareable-link-id>');
link.searchParams.set('contact_id', 'customer_123');
link.searchParams.set('contact_email', 'alice@example.com');
link.searchParams.set('contact_display_name', 'Alice & Bob');
link.searchParams.set('contact_plan', 'pro');
console.log(link.toString());This correctly percent-encodes characters such as @, spaces, &, +, and Unicode characters in trait values.
Avoid unnecessary personal data in URLs
Query parameters can appear in browser history, email security systems, proxy and server logs, analytics tools, referrer information, and copied links. Prefer an opaque contact_id and include only the traits needed for the survey. Never include passwords, secret keys, access tokens, or sensitive personal data.
Invalid parameters
Invalid contact parameters are ignored independently. They do not prevent other valid contact or response parameters from being processed.
A contact parameter may be ignored when:
- The same parameter appears more than once.
- Its value is empty.
contact_idcontains unsupported characters or exceeds 50 characters.contact_emailis not a valid email address.- A trait slug contains uppercase letters, hyphens, brackets, or other unsupported characters.
- Bracketed or nested contact syntax is used.
- The link supplies more than 25 custom contact traits.
- A signature timestamp is malformed or is provided without a signature.
- A signature is provided without
contact_idorcontact_email.
Unlike multi-value response questions, contact parameters do not support repeated values, comma-separated lists, or bracketed member keys.
Persistence and source tracking
Contact identity and accepted traits participate in the retained-draft scope. Opening links for two different contacts in the same browser does not restore one contact's draft into the other contact's form.
Signature and timestamp values do not participate in the draft identity, so regenerating a signature for the same contact and traits does not create another draft scope.
All contact_ and response_ parameters are excluded from Source Tracking. Other URL parameters continue to follow the form's source-tracking configuration.
Related
Was this page helpful?
