More in Getting started
- Install TapCub on your website
- Migrate from Google Analytics 4 or Baidu Tongji
- Add a website, app or mini-program
- How do I add TapCub to WordPress?
- How do I add TapCub to Shopify?
- Where do I paste the TapCub tracking code?
- Can I install TapCub with Google Tag Manager?
- How do I track a React, Vue or Next.js app?
- How do I check that TapCub is collecting data?
- Why does TapCub show no data after I installed it?
- What is a site, and how many can I add?
- Which time zone should I pick for a site?
- Which domains do I need to register?
- How do I keep my own visits out of the reports?
- Why does my visitor count differ from Google Analytics 4?
- Can I run TapCub alongside Google Analytics 4?
- How do I move my goals and events from GA4?
- Can I import my historical data from GA4?
- How do I add TapCub to Squarespace?
- How do I add TapCub to Wix?
- Which Content Security Policy rules does TapCub need?
- Do ad blockers block TapCub?
- How do I send events from my server?
- How do I install TapCub on React?
- How do I install TapCub on Nuxt?
- How do I install TapCub on Vue?
- How do I install TapCub on Next.js?
- How do I capture a HAR file for TapCub support?
- How do I create and manage API keys?
- All guides in this category
Still have a question?
Could not find it? A person reads every message, usually within a few hours on business days.
Chat with usShort answer
Send a POST to https://api.pathclue.com/api/v1/track with a key that has the Server track scope in the Authorization: Bearer header and a JSON body {"events": [ … ]} holding 1 to 1,000 events. Add ?debug=1 while integrating: the server validates every event and returns per-item results without storing anything.
Use the HTTP API when there is no server SDK for your language, or when you send from a gateway or a job runner. If an SDK exists for your stack (Node.js, Python, PHP, Java, Go), prefer it: it already batches, retries and flushes. See Send events from your server.
Before you start
- Create a project API key with the Server track (
track:write) scope: Create and manage API keys. - Keep the key on the server only, for example in
TAPCUB_API_KEY. - Keep pageviews on the website script. The HTTP API is for business events (orders, payments, sign-ups) and profile updates, not for page views.
Send your first event
curl -X POST "https://api.pathclue.com/api/v1/track?debug=1" \
-H "Authorization: Bearer $TAPCUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [{
"type": "track",
"event": "purchase",
"login_id": "u_1001",
"insert_id": "ord_1001",
"time": 1759363200123,
"properties": { "revenue": 19.9, "currency": "USD" },
"context": { "platform": "server" }
}]
}'
A debug response has debug: true and one entry in results per event, with any warnings. When it is clean, remove ?debug=1 and send again. The event appears in All-platform analytics › Data › Events & properties.
Event fields
| Field | Notes |
|---|---|
type | Defaults to track. See the table below |
event | Event name, 1 to 100 characters. Required for track |
login_id / device_id | Who did it. Use login_id for signed-in users; device_id (up to 72 characters) for anonymous ones |
time | Unix milliseconds. More than 72 hours from the server clock is replaced with the current time and returned as a warning |
insert_id | Up to 36 characters. Idempotency key: the first event with this ID is kept. Use the order or payment ID |
session_id | Up to 32 characters. Without it the event is stored but does not join session metrics |
properties | Event or profile properties |
group | type:id, for example company:acme, to attach the event to an account |
context | ip, user_agent, url, platform, country, lang, and campaign for sign-up attribution |
Event types
type | Use it to |
|---|---|
track | Record a business event (the default) |
track_signup | Record a sign-up and link the anonymous device to the new login_id |
bind / unbind | Add or remove identities such as email or mobile (sent in identities) |
profile_set, profile_set_once, profile_unset, profile_increment, profile_append | Update user profile properties |
item_set / item_delete | Write dimension rows such as products or articles, with item_type and item_id |
track_update / track_overwrite | Merge into or replace a stored event's properties; insert_id is required |
group_set | Set traits of an account (group) |
Example: update a profile and bind an email in one request.
{ "events": [
{ "type": "profile_set", "login_id": "u_1001", "properties": { "plan": "pro", "$name": "Ada" } },
{ "type": "bind", "login_id": "u_1001", "identities": { "email": "ada@example.com" } }
] }
An email or mobile that is not already a 64-character hex hash is hashed by the server before storage, and the item returns the warning plaintext_identity_hashed. Hash it yourself (SHA-256) to avoid sending plaintext at all.
Read the response
A successful call returns received, accepted, rejected, events (rows queued) and results. Outside debug mode results lists only items that failed or produced a warning: index is the item's position in events, and ok: false means that item was not stored. Other items in the same request are still accepted.
Add validation_behavior=enforce to the query to reject any item that produces a warning, for example to make sure no plaintext email is ever accepted.
Errors, limits and retries
| Response | Meaning | What to do |
|---|---|---|
400 VALIDATION | The body breaks the schema | Read issues; the whole request is rejected |
401 NO_API_KEY / BAD_API_KEY | Key missing, wrong, revoked or expired | Check the header and the key |
403 | Key lacks the Server track scope | Use a key with track:write |
413 PAYLOAD_TOO_LARGE | Body over 2 MB | Split into smaller batches |
429 RATE_LIMIT | Over 600 requests per minute for this key | Wait retryAfter seconds, then retry with backoff |
5xx | Server error | Retry with exponential backoff |
Retry rules: keep the same insert_id on every retry so nothing is counted twice, back off exponentially, cap the number of attempts, and batch events (up to 1,000 per request) instead of sending one request per event.
Related
Did this answer your question?
We use your answers to fix and expand this page.
Couldn’t send. Please try again in a minute.
Thanks for the feedback. We’ll use it to improve this page.You’ve already sent feedback on this page. Thanks.