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

  1. Open Integrations, create an HTTP source under Data in, and open its detail page.
  2. 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.
  3. Send a JSON batch with a signature over the complete, unmodified request body. For example, from a shell with curl and openssl:
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.

OperationRequired fieldsEffect
identifyAt least one of userId or anonymousId; optional traits objectSupplies user identity and traits. Both IDs may be supplied together.
trackevent; optional userId, anonymousId, and properties objectRecords an event, with or without user identity.
graph.setNon-user subject: { collection, id } and properties objectSupplies properties for that subject.
graph.connectfrom and to subject objectsConnects the directed pair.
graph.disconnectfrom and to subject objectsDisconnects 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.