HTTP source
Send signed events, user traits, and relationship data from your server.
- Last reviewed
Use an HTTP source when your server needs to send user traits, events, or
relationships directly to getuserfeedback.com. It accepts identify, track,
graph.set, graph.connect, and graph.disconnect.
Set up and send a batch
- Open Integrations, create an HTTP source under Data in, and open its detail page.
- Copy the endpoint URL and Signing secret from that page. A production
URL looks like
https://http.ingest.getuserfeedback.com/int_<id>; use the exact URL shown for your integration. - Send a JSON batch with a signature over the complete, unmodified request
body. For example, from a shell with
curlandopenssl:
url='https://http.ingest.getuserfeedback.com/int_<id>' # Replace with your copied URLsecret='<signing-secret>'body='{"version":1,"batch":[{"type":"identify","messageId":"user-123-v1","userId":"user-123","traits":{"plan":"pro"}}]}'signature=$(printf %s "$body" | openssl dgst -sha256 -hmac "$secret" -binary | od -An -tx1 | tr -d ' \n')curl -i -X POST "$url" \-H 'Content-Type: application/json' \-H "X-GX-Signature: v1=$signature" \--data-binary "$body"Keep the signing secret on your server. The signature is HMAC-SHA256 of the
entire body as sent, formatted as v1= followed by 64 lowercase hex
characters. Changing whitespace or re-serializing the JSON after signing
invalidates it.
When rotating the signing secret, update your server's copy before the old secret expires. Immediate revocation stops requests signed with the old secret.
Batch format
The top-level JSON object must contain version: 1 and a nonempty batch
array. Each operation needs its own nonblank messageId and may include a
timestamp (an ISO 8601 UTC date-time ending in Z, with seconds or
milliseconds). If omitted, the acceptance time is used.
For non-user graph subjects, first create the matching Group in
Groups settings. Use that Group's key as the subject
collection, such as account.
| Operation | Required fields | Effect |
|---|---|---|
identify | At least one of userId or anonymousId; optional traits object | Supplies user identity and traits. Both IDs may be supplied together. |
track | event; optional userId, anonymousId, and properties object | Records an event, with or without user identity. |
graph.set | Non-user subject: { collection, id } and properties object | Supplies properties for that subject. |
graph.connect | from and to subject objects | Connects the directed pair. |
graph.disconnect | from and to subject objects | Disconnects the directed pair. |
For example, {"collection":"account","id":"acct-123"} is a non-user
subject. Use the same from and to pair to disconnect a connection. To send
a user event, include an operation such as:
{"type": "track","messageId": "dashboard-opened-123","userId": "user-123","event": "Dashboard Opened","properties": { "surface": "web" }}Omit both IDs on track to record an event without a user actor. Supplied IDs
must be nonblank strings, at most 255 characters after trimming and
normalization. track and identify do not accept a subject object;
collection-qualified refs remain explicit fields of graph operations.
Send at most 100 operations and 1 MiB of JSON per batch. Across a batch, keep to 100 total identify traits, 100 total track property fields (including fields inside nested objects), and 100 total graph properties. Arrays count as one property value; fields inside array items are not separate event-property paths.
Responses and retries
202 {"accepted":true} means the batch's source evidence was committed. It
does not mean downstream processing or audience updates have completed;
there is no initial backfill or freshness guarantee. A repeated messageId
within the same integration does not replace stored input: the first stored
operation wins, including when an ID repeats within one batch. Use a new ID
for a changed operation.
Fix the request before retrying a 400 (invalid request), 401 (missing or
invalid signature), 413 (body too large), or 415 (unsupported media type).
404 means the integration is unavailable, including when it is paused or
deleted. A 500 is a server error; retry with the same message IDs so already
stored operations are not replaced.