Docs·Tracking
/1.0/track/identifyIdentify a visitor
Ties a visitor, meaning one browser, to a person, found by email address. From then on, that
browser's visits and events, the earlier ones included, count for the person. Someone who signs in on
their phone and their laptop is counted once, and appears on the Profiles page under their email
with the details you send in attributes.
Where the tracking script runs, call Spreelytics.identify(email, attributes) when someone signs up or
signs in, and the script sends this request for you (see Identify users). Call the
route yourself where the script cannot run, or from your server with the visitor id the browser
handed it.
The request
POST https://sdk.spreelytics.com/1.0/track/identify, in either encoding:
- Form, as the script sends it:
Content-Type: application/x-www-form-urlencoded, with aclientKeyfield holding your client key and adatafield holding the JSON object below as a string. - JSON:
Content-Type: application/json, the JSON object below as the body, and the key in the address:?clientKey=YOUR_CLIENT_KEY. LeaveclientKeyout of the JSON body. This route does not accept the field and answers400.
Your client key is in Settings → API keys, under Site tracking key. Getting started covers both encodings in more detail.
Fields
| Field | Type | Required | What it is |
|---|---|---|---|
visitorId | string | Yes | The browser to tie to the person, the same id its pageviews carry. On a page that runs the script, Spreelytics.getVisitorId() returns it. |
identifiers | object | Yes | Holds the email address: { "email_id": "ada@example.com" }. |
identifiers.email_id | string | Yes | The person's email address. See The email address. |
attributes | object | No | Details to save on the person. See Person attributes. |
This route takes no sessionId and no timestamp. Sending either one, or any other field, makes
the request fail with 400.
The email address
Email is the only way to identify a person. There is no user id or alias form.
Spreelytics does not check the address. The script skips anything that does not look like an email
(text, an @, more text, a dot, more text) and sends nothing for it, so check the address yourself
before you call the route.
Send the address in lower case, without spaces. An existing person is only found when the address
matches exactly, letter case included, and new people are normally stored in lower case. So
Ada@Example.com would not find ada@example.com, and a second person would be created instead.
What happens to the visitor
- If a person with this email exists in the audience, the visitor is tied to them. If not, a new person is created with this email.
- The visitor's visits and events from before the call now count for that person too, so the visits that led up to a signup appear on the new person's profile.
- If the visitor was already tied to a person with a different email, it moves to the person you name now. That is what happens when two people sign in on the same computer.
- If the visitor had never been seen before, it is recorded now, already tied to the person.
- Calling the route again with the same visitor and email changes nothing but the attributes, so calling it on every sign-in is safe.
Identify calls are not counted as events, and they are not stopped by the hard limit on your plan's allowance.
Person attributes
attributes is an object of details about the person. These keys fill the person's built-in fields,
and take text:
| Key | Field |
|---|---|
first_name, last_name | First and last name |
company, website | Company and company domain |
phone | Phone number |
address, address_line2, city, state, zip, country | Postal address |
lang | Language |
Any other key with a text, number or true or false value is saved as a custom attribute under that
key, such as "plan": "growth" or "seats": 5. A value that is null, an object or a list is
ignored. A built-in key with a value that is not text, such as a number sent as phone, is saved as
a custom attribute instead.
Attributes are saved in the background, shortly after the call answers. A new value replaces the old one. Most built-in fields can also be used in segment rules, under Contact.
What it answers
| Answer | What it means |
|---|---|
200 with an empty body | Accepted. The link and the attributes are saved shortly after. |
200 with the body OK | Dropped and not stored. See below. |
400 | A required field is missing or has the wrong type, or the body has a field this route does not accept, clientKey included. The JSON answer names each problem under fields. |
401 with the body Event API: Unauthorised | No client key, an unknown client key, or a request from a site that is not in Allowed domains (Settings → Details). |
413 | The body is larger than 250,000 bytes. |
500 | In the form encoding, data is not valid JSON. |
A call is dropped, and still answered with 200 and OK, when its User-Agent belongs to a bot, a
crawler, a command line tool or an HTTP library (curl, Python's requests, axios, node-fetch and
others) or names a headless browser or test tool, and when it comes from an address in the published
ranges of Amazon Web Services, Google Cloud, Oracle Cloud, DigitalOcean or Linode. The full rules are
in What the Tracking API drops.
Calling it from a server
A common reason to identify from a server is that sign-in happens there. Have the page that starts
the sign-in send Spreelytics.getVisitorId() along with the form, then call this route once the
sign-in succeeds.
- Check where your server runs. A request from Amazon Web Services, Google Cloud, Oracle Cloud, DigitalOcean or Linode is dropped, whatever it contains. Vercel and other hosts built on those clouds are included.
- Send a browser's User-Agent. Your HTTP library's own User-Agent is dropped as a bot. Forwarding the visitor's own is the simplest way to pass the check.
- Send an
Originheader with a hostname from Allowed domains, such ashttps://www.example.com, or the call is refused with401.
On a cookieless audience
With cookieless tracking on, the collector ignores the visitorId you send and works
out the visitor from the request's address and User-Agent. From the visitor's browser, that is the
right visitor. From a server, it is a visitor made from your server's address, so the person would be
tied to the wrong one. On a cookieless audience, identify people from the browser.
Request
# curl's own User-Agent is dropped as a tool, so this sends a browser's.
curl -X POST 'https://sdk.spreelytics.com/1.0/track/identify?clientKey=YOUR_CLIENT_KEY' \
-H 'Content-Type: application/json' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36' \
-H 'Origin: https://www.example.com' \
-d '{
"visitorId": "vid_6f1c2a4e-8d3b-4c55-9a7e-2b8f0c9d1e23",
"identifiers": { "email_id": "ada@example.com" },
"attributes": { "first_name": "Ada", "company": "Acme", "plan": "growth" }
}'
// In a browser, without the tracking script. These are the ids saved by
// the browser sample on Track a pageview.
const ids = JSON.parse(localStorage.getItem('my_ids'));
const email = 'Ada@Example.com'.trim().toLowerCase();
await fetch('https://sdk.spreelytics.com/1.0/track/identify', {
method: 'POST',
body: new URLSearchParams({
clientKey: 'YOUR_CLIENT_KEY',
data: JSON.stringify({
visitorId: ids.visitorId,
identifiers: { email_id: email },
attributes: { first_name: 'Ada', company: 'Acme', plan: 'growth' },
}),
}),
});
# On your server, after a successful sign-in. visitor_id came from the
# browser (Spreelytics.getVisitorId()).
import requests
requests.post(
"https://sdk.spreelytics.com/1.0/track/identify",
params={"clientKey": "YOUR_CLIENT_KEY"},
headers={
# The visitor's own User-Agent. The requests default is dropped as a tool.
"User-Agent": visitor_user_agent,
# A hostname from Allowed domains.
"Origin": "https://www.example.com",
},
json={
"visitorId": visitor_id,
"identifiers": {"email_id": user.email.strip().lower()},
"attributes": {"first_name": user.first_name, "plan": user.plan},
},
)
Response
200 OK
(empty body)
Related
- Identify users: identifying people from the page with the script.
- Profiles: where identified people and their attributes show up.
- Track an event: events whose
attributesupdate the person once they are identified.