Skip to content

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-Key header 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 source and events fields
  • Each event in events has type and data fields
  • The data field is an object (not a string or array)
  • The events array 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.