# Insights API

The **Insights API** gives access to the usage database of **The Wallet Crew (TWC)** platform. Query Logs, Events, and Metrics using [Kusto Query Language (KQL)](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/).

This API is designed for **technical users extracting data programmatically**, but queries remain understandable for medium-technical users as well.

## Authentication and permissions

Access requires standard **TWC authentication**.

* Permission required: **`Insights:Read`**
* Authentication flow: use your existing TWC auth token (e.g., from login or service-to-service).
* Single-tenant scope: you can only query data from your own tenant.

Example header:

```http
Authorization: Bearer <your_access_token>
```

## Retention and rate limits

* **Logs**: retained **45 days**
* **Events**: retained **indefinitely**
* **Metrics**: retained **indefinitely**

**Rate limit**: 60 API calls per minute. To request higher limits, open a support ticket.

## Endpoint

All queries are executed via:

```http
POST /api/{tenantId}/insights/query
```

* `{tenantId}` = your tenant identifier
* Request body must contain a `query` string in **KQL**

## Tables and schema

The Insights database contains three tables:

### Logs

| Column      | Type     |
| ----------- | -------- |
| eventId     | guid     |
| timestamp   | datetime |
| tenantId    | string   |
| eventType   | string   |
| operationId | string   |
| properties  | dynamic  |

Contains errors and traces related to platform activity. Useful for debugging and monitoring health.

### Events

| Column      | Type     |
| ----------- | -------- |
| eventId     | guid     |
| timestamp   | datetime |
| tenantId    | string   |
| eventType   | string   |
| operationId | string   |
| properties  | dynamic  |

Contains:

* Page views
* API requests
* Custom business events

### Metrics

| Column     | Type     |
| ---------- | -------- |
| metricId   | guid     |
| tenantId   | string   |
| metricType | string   |
| value      | dynamic  |
| properties | dynamic  |
| timestamp  | datetime |

Represents **snapshots of the system state**, taken hourly.

## Run queries

### Example with Axios (JavaScript)

```ts
const result = await axios.post<{ rows: Array<Array<unknown>> }>(
  `/api/${tenantId}/insights/query`,
  {
    query: `
Events 
| where eventType == "Customer:Upserted" 
| summarize count()`,
  }
);

console.log(result.data.rows);
```

### Example with cURL

```bash
curl -X POST "https://<your-host>/api/<tenantId>/insights/query" \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Events | where eventType == \"Customer:Upserted\" | summarize count()"
  }'
```

## Common queries

### Count new customers

```kql
Events
| where eventType == "Customer:Upserted"
| summarize NewCustomers = count()
```

### Count pass installations

```kql
Events
| where eventType == "Pass:Installed"
| summarize PassInstallations = count()
```

### Count requests per day

```kql
Events
| where eventType == "Request"
| summarize RequestsPerDay = count() by bin(timestamp, 1d)
```

### Count redirects per day

```kql
Events
| where eventType == "Redirect:Redirected"
| summarize RedirectsPerDay = count() by bin(timestamp, 1d)
```

### Count page views per browser

```kql
Events
| where eventType == "PageView"
| extend browser = tostring(properties.browser)
| summarize PageViews = count() by browser
```

## Common event types

Here are some of the most common `eventType` values you may want to query:

* **Customer lifecycle**
  * `Customer:Upserted`
  * `Y2:Customer:Created`
  * `Y2:Customer:Updated`
* **Pass lifecycle**
  * `Pass:Created`
  * `Pass:Updated`
  * `Pass:Installed`
  * `Pass:Uninstalled`
* **User actions**
  * `action:addToAppleWallet`
  * `action:addToGoogleWallet`
  * `action:loginWithGoogle`
  * `action:loginWithApple`
* **Tracking & analytics**
  * `Request`
  * `PageView`
  * `Redirect:Redirected`
  * `step:complete`
  * `step:changed`

## Troubleshooting

* **401 Unauthorized**
  * Ensure your token is valid and includes `Insights:Read`.
* **429 Too Many Requests**
  * You exceeded the rate limit (60 calls/minute). Implement retries with exponential backoff.
* **Query takes too long**
  * Simplify query or reduce time window.
  * Avoid unbounded queries on large tables.

## FAQ

<details>

<summary>Can I export results to CSV/JSON?</summary>

Not directly via the API.

Consume the JSON response and convert it locally.

</details>

<details>

<summary>Can I query multiple tenants?</summary>

No.

Access is restricted to your tenant only.

</details>

<details>

<summary>Does the Insights DB contain personal data?</summary>

No.

It does not contain PII.

</details>

<details>

<summary>Can I set up alerts (thresholds, triggers)?</summary>

Not at the moment.

</details>
