Custom API Integration¶
Send events to Adwize from any backend system, application, or service using the REST API. This integration gives you full control over event ingestion and is ideal for server-side tracking, batch imports, or custom data pipelines.
Overview¶
The Custom API integration allows you to send events to Adwize from any system that can make HTTP requests. Use this when you want to:
- Send events from your backend application
- Forward events from data pipelines or ETL processes
- Import historical data in batches
- Integrate with services that don't have native Adwize connectors
Authentication¶
All API requests require authentication using an API key in the X-API-Key header. See the Authentication guide for details on obtaining and using your API key.
Keep your API key secret
Your API key grants full access to your tenant's data. Never expose it in client-side code. Use it only in server-side applications or secure environments.
Sending Events¶
Send events using the POST /api/v1/events endpoint. The request body is an event batch object containing a source identifier and an events array.
curl https://api.getadwize.com/api/v1/events \
-X POST \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key-here" \
-d '{
"source": "backend",
"events": [
{
"type": "purchase",
"data": {
"transaction_id": "TXN-001",
"value": 99.99,
"currency": "USD"
}
},
{
"type": "signup",
"data": {
"user_id": "usr_abc123",
"plan": "pro"
}
}
]
}'
import httpx
batch = {
"source": "backend",
"events": [
{
"type": "purchase",
"data": {
"transaction_id": "TXN-001",
"value": 99.99,
"currency": "USD",
},
},
{
"type": "signup",
"data": {
"user_id": "usr_abc123",
"plan": "pro",
},
},
],
}
response = httpx.post(
"https://api.getadwize.com/api/v1/events",
json=batch,
headers={"X-API-Key": "your-api-key-here"},
)
response.raise_for_status()
print(response.json())
const batch = {
source: "backend",
events: [
{
type: "purchase",
data: {
transaction_id: "TXN-001",
value: 99.99,
currency: "USD"
}
},
{
type: "signup",
data: {
user_id: "usr_abc123",
plan: "pro"
}
}
]
};
const response = await fetch("https://api.getadwize.com/api/v1/events", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "your-api-key-here"
},
body: JSON.stringify(batch)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
console.log(`Ingested ${result.events_received} events`);
Event Batch Schema¶
The request body is an event batch object with the following structure:
Batch Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
source |
string | Yes | Source identifier (e.g., backend, api, etl) |
source_id |
string | No | Optional source instance identifier |
events |
array | Yes | Array of event objects (minimum 1) |
Event Fields¶
Each object in the events array accepts the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | Event type identifier (e.g., purchase, signup, page_view) |
data |
object | Yes | Arbitrary event payload containing your event data |
timestamp |
string (ISO 8601) | No | Event timestamp. Defaults to the time the event is received |
metadata |
object | No | Optional metadata (e.g., SDK version, environment) |
The data field can contain any JSON-serializable object. Adwize stores this data as-is and uses it for quality monitoring rules.
Best Practices¶
Batch Events¶
Send multiple events in a single request to reduce overhead and improve throughput. The API accepts up to 1,000 events per batch.
{
"source": "backend",
"events": [
{"type": "event_a", "data": {"key": "value"}},
{"type": "event_b", "data": {"key": "value"}},
{"type": "event_c", "data": {"key": "value"}}
]
}
Use Meaningful Source Names¶
Choose descriptive source identifiers that help you identify where events originated:
- Good:
backend,api,etl,mobile-app - Avoid:
source1,test,temp
Include Identifying Fields¶
Include fields in the data object that help identify and correlate events:
- User identifiers (
user_id,email,customer_id) - Session identifiers (
session_id,request_id) - Timestamps (
timestamp,created_at) - Contextual data (
page_url,referrer,user_agent)
Handle Rate Limits¶
The Events API has a rate limit of 1,000 requests per minute. If you exceed this limit, you'll receive a 429 Too Many Requests response. Implement exponential backoff and retry logic:
import time
import httpx
def send_events_with_retry(batch, max_retries=3):
for attempt in range(max_retries):
try:
response = httpx.post(
"https://api.getadwize.com/api/v1/events",
json=batch,
headers={"X-API-Key": "your-api-key-here"},
)
response.raise_for_status()
return response
except httpx.HTTPStatusError as e:
if e.response.status_code == 429:
wait_time = 2 ** attempt
time.sleep(wait_time)
continue
raise
Error Handling¶
401 Unauthorized¶
The API key is missing or invalid. Check that:
- The
X-API-Keyheader is included in your request - The API key is correct (copy from Settings > API Keys)
- The API key hasn't been rotated or revoked
403 Forbidden¶
The API key doesn't have permission to perform this action, or the domain isn't allowed. Check your API key settings in Adwize.
429 Too Many Requests¶
You've exceeded the rate limit of 1,000 requests per minute. Implement exponential backoff and retry the request after waiting.
400 Bad Request¶
The request body is malformed or missing required fields. Verify that:
- The request body is valid JSON
- The body is an object with
sourceandeventsfields - Each event in
eventshastypeanddatafields - The
datafield is an object (not a string or array) - The
eventsarray contains at least one event
Response¶
On success, the API returns 201 Created with a JSON response:
{
"success": true,
"events_received": 2,
"events": [
{
"id": "a1b2c3d4-...",
"tenant_id": "e5f6g7h8-...",
"source": "backend",
"event_type": "purchase",
"received_at": "2026-03-01T12:00:00"
},
{
"id": "i9j0k1l2-...",
"tenant_id": "e5f6g7h8-...",
"source": "backend",
"event_type": "signup",
"received_at": "2026-03-01T12:00:00"
}
]
}
Full API Reference¶
For complete details on the Events API, including query parameters, response formats, and additional endpoints, see the Events API Reference.