> For the complete documentation index, see [llms.txt](https://docs.thewalletcrew.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.thewalletcrew.io/developers-guides/integration-guides/insights-api.md).

# Insights API

## Insights API

The **Insights API** gives access to the usage database of The Wallet Crew. 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 teams extracting data programmatically.

<details>

<summary><strong>Real-world examples</strong></summary>

* Query pass installation trends by day after a campaign launch.
* Export webhook or scan activity into a BI pipeline.
* Inspect platform logs while debugging a tenant-specific integration issue.

</details>

### Authentication and permissions

Access requires standard The Wallet Crew authentication.

* Permission required: **`Insights:Read`**
* Authentication flow: use an existing The Wallet Crew auth token (for example, from login or service-to-service).
* Single-tenant scope: you can only query data from your own tenant.

Send the access token through the `Authorization` header.

### 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 use this operation:

## Execute analytics query

> Runs a custom analytics query and returns results in tabular format.\
> \
> \## Authorization\
> Requires \`Insights.Read\` scope.\
> \
> \## Rate Limiting\
> Limited to 60 requests per interval to protect analytics infrastructure.\
> \
> \## Query Language\
> Typically uses Kusto Query Language (KQL) syntax:\
> \`\`\`kql\
> Passes\
> \| where timestamp > ago(7d)\
> \| summarize count() by passType\
> \| order by count\_ desc\
> \`\`\`\
> \
> \## Parameters\
> Supports parameterized queries for security and reusability:\
> \`\`\`json\
> {\
> &#x20; "query": "Events | where Name == name | take 100",\
> &#x20; "parameters": { "name": "Pass:Installed" }\
> }\
> \`\`\`\
> \## Use Cases\
> \- Custom dashboards\
> \- Business intelligence reports\
> \- Data exports\
> \- Trend analysis\
> \
> \## Performance\
> \- Query timeout: Configurable per tenant\
> \- Result limits: May be enforced\
> \- Caching: Not automatic - implement client-side if needed

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Insights"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"QueryRequest":{"required":["query"],"type":"object","properties":{"query":{"type":"string"},"parameters":{"type":"object","additionalProperties":{"type":"string"}},"options":{"$ref":"#/components/schemas/QueryOptions"}},"additionalProperties":false},"QueryOptions":{"type":"object","additionalProperties":false},"QueryResponse":{"type":"object","properties":{"columns":{"type":"array","items":{"type":"string"}},"rows":{"type":"array","items":{"type":"array","items":{}}}},"additionalProperties":false},"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}},"paths":{"/api/{tenantId}/insights/query":{"post":{"tags":["Insights"],"summary":"Execute analytics query","description":"Runs a custom analytics query and returns results in tabular format.\n\n## Authorization\nRequires `Insights.Read` scope.\n\n## Rate Limiting\nLimited to 60 requests per interval to protect analytics infrastructure.\n\n## Query Language\nTypically uses Kusto Query Language (KQL) syntax:\n```kql\nPasses\n| where timestamp > ago(7d)\n| summarize count() by passType\n| order by count_ desc\n```\n\n## Parameters\nSupports parameterized queries for security and reusability:\n```json\n{\n  \"query\": \"Events | where Name == name | take 100\",\n  \"parameters\": { \"name\": \"Pass:Installed\" }\n}\n```\n## Use Cases\n- Custom dashboards\n- Business intelligence reports\n- Data exports\n- Trend analysis\n\n## Performance\n- Query timeout: Configurable per tenant\n- Result limits: May be enforced\n- Caching: Not automatic - implement client-side if needed","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"The query text, parameters, and optional execution settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryRequest"}},"text/json":{"schema":{"$ref":"#/components/schemas/QueryRequest"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/QueryRequest"}}}},"responses":{"200":{"description":"Query executed successfully","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/QueryResponse"}},"application/json":{"schema":{"$ref":"#/components/schemas/QueryResponse"}},"text/json":{"schema":{"$ref":"#/components/schemas/QueryResponse"}}}},"400":{"description":"Invalid query syntax or parameters","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"Not authorized","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Internal server error while executing 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.

### 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>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.thewalletcrew.io/developers-guides/integration-guides/insights-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
