Ingest product events
curl --request POST \
--url https://app.gaintrace.com/api/v1/events \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"events": [
{
"event_name": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"account_id": "<string>",
"user_id": "<string>",
"anonymous_id": "<string>",
"session_id": "<string>",
"event_category": "<string>",
"feature_name": "<string>",
"source": "<string>",
"source_event_id": "<string>",
"value": 123,
"unit": "<string>",
"is_programmatic": true,
"properties": {}
}
]
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
events: [
{
event_name: '<string>',
timestamp: '2023-11-07T05:31:56Z',
account_id: '<string>',
user_id: '<string>',
anonymous_id: '<string>',
session_id: '<string>',
event_category: '<string>',
feature_name: '<string>',
source: '<string>',
source_event_id: '<string>',
value: 123,
unit: '<string>',
is_programmatic: true,
properties: {}
}
]
})
};
fetch('https://app.gaintrace.com/api/v1/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.gaintrace.com/api/v1/events"
payload = { "events": [
{
"event_name": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"account_id": "<string>",
"user_id": "<string>",
"anonymous_id": "<string>",
"session_id": "<string>",
"event_category": "<string>",
"feature_name": "<string>",
"source": "<string>",
"source_event_id": "<string>",
"value": 123,
"unit": "<string>",
"is_programmatic": True,
"properties": {}
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"data": {
"inserted": 123,
"duplicates": 123,
"linked": 123,
"errors": 123
},
"validation_errors": [
{
"index": 123,
"error": "<string>"
}
]
}{
"error": {
"code": "bad_request",
"message": "Invalid JSON body",
"doc_url": "https://docs.gaintrace.com/errors#bad_request"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing Authorization header",
"doc_url": "https://docs.gaintrace.com/errors#unauthorized"
}
}{
"error": {
"code": "payment_required",
"message": "Monthly event limit reached. Upgrade or enable overage billing.",
"doc_url": "https://docs.gaintrace.com/errors#payment_required"
}
}{
"error": {
"code": "forbidden",
"message": "Insufficient scope: write:companies required",
"doc_url": "https://docs.gaintrace.com/errors#forbidden"
}
}{
"error": {
"code": "unprocessable_entity",
"message": "Request validation failed. name: name is required",
"doc_url": "https://docs.gaintrace.com/errors#unprocessable_entity"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Maximum 120 requests per minute per API key.",
"doc_url": "https://docs.gaintrace.com/errors#rate_limit_exceeded"
}
}{
"error": {
"code": "internal_server_error",
"message": "Something went wrong. Try again in a moment.",
"doc_url": "https://docs.gaintrace.com/errors#internal_server_error"
}
}{
"error": {
"code": "service_unavailable",
"message": "We had trouble reaching the database. Try again in a moment.",
"doc_url": "https://docs.gaintrace.com/errors#service_unavailable"
}
}{
"error": {
"code": "gateway_timeout",
"message": "The request timed out. Try again in a moment.",
"doc_url": "https://docs.gaintrace.com/errors#gateway_timeout"
}
}Ingest
Ingest product events
Ingests a batch of product-usage events (Segment-style). Feeds health, signals, and activation recompute.
Accepts server keys (gt_live_, scope write:events) or client-safe browser keys (gt_pub_, scope write:ingest). Public ingest is CORS-enabled.
Scope: write:events or write:ingest · Max 1000 events per request.
POST
/
events
Ingest product events
curl --request POST \
--url https://app.gaintrace.com/api/v1/events \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"events": [
{
"event_name": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"account_id": "<string>",
"user_id": "<string>",
"anonymous_id": "<string>",
"session_id": "<string>",
"event_category": "<string>",
"feature_name": "<string>",
"source": "<string>",
"source_event_id": "<string>",
"value": 123,
"unit": "<string>",
"is_programmatic": true,
"properties": {}
}
]
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
events: [
{
event_name: '<string>',
timestamp: '2023-11-07T05:31:56Z',
account_id: '<string>',
user_id: '<string>',
anonymous_id: '<string>',
session_id: '<string>',
event_category: '<string>',
feature_name: '<string>',
source: '<string>',
source_event_id: '<string>',
value: 123,
unit: '<string>',
is_programmatic: true,
properties: {}
}
]
})
};
fetch('https://app.gaintrace.com/api/v1/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.gaintrace.com/api/v1/events"
payload = { "events": [
{
"event_name": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"account_id": "<string>",
"user_id": "<string>",
"anonymous_id": "<string>",
"session_id": "<string>",
"event_category": "<string>",
"feature_name": "<string>",
"source": "<string>",
"source_event_id": "<string>",
"value": 123,
"unit": "<string>",
"is_programmatic": True,
"properties": {}
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"data": {
"inserted": 123,
"duplicates": 123,
"linked": 123,
"errors": 123
},
"validation_errors": [
{
"index": 123,
"error": "<string>"
}
]
}{
"error": {
"code": "bad_request",
"message": "Invalid JSON body",
"doc_url": "https://docs.gaintrace.com/errors#bad_request"
}
}{
"error": {
"code": "unauthorized",
"message": "Missing Authorization header",
"doc_url": "https://docs.gaintrace.com/errors#unauthorized"
}
}{
"error": {
"code": "payment_required",
"message": "Monthly event limit reached. Upgrade or enable overage billing.",
"doc_url": "https://docs.gaintrace.com/errors#payment_required"
}
}{
"error": {
"code": "forbidden",
"message": "Insufficient scope: write:companies required",
"doc_url": "https://docs.gaintrace.com/errors#forbidden"
}
}{
"error": {
"code": "unprocessable_entity",
"message": "Request validation failed. name: name is required",
"doc_url": "https://docs.gaintrace.com/errors#unprocessable_entity"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Maximum 120 requests per minute per API key.",
"doc_url": "https://docs.gaintrace.com/errors#rate_limit_exceeded"
}
}{
"error": {
"code": "internal_server_error",
"message": "Something went wrong. Try again in a moment.",
"doc_url": "https://docs.gaintrace.com/errors#internal_server_error"
}
}{
"error": {
"code": "service_unavailable",
"message": "We had trouble reaching the database. Try again in a moment.",
"doc_url": "https://docs.gaintrace.com/errors#service_unavailable"
}
}{
"error": {
"code": "gateway_timeout",
"message": "The request timed out. Try again in a moment.",
"doc_url": "https://docs.gaintrace.com/errors#gateway_timeout"
}
}Authorizations
Bearer API key. Secret server keys start with gt_live_; client-safe browser keys start with gt_pub_ (write-only, origin-pinned). Create and scope keys in Settings → API Keys.
Body
application/json
Required array length:
1 - 1000 elementsShow child attributes
Show child attributes
Last modified on July 7, 2026
Was this page helpful?
⌘I