# Analytics
URL: https://openship.io/docs/api/analytics.md

Read project traffic, deployment statistics, and resource usage.

Analytics report traffic, deployment outcomes, and runtime usage for resources the caller can access.
Project methods take a project ID in the SDK; REST uses `?projectId=`. Server methods take a server ID.

## Read request traffic

`overview` returns the cumulative summary and time-series periods together. Use `summary` or `periods`
when you only need one. `geo` adds geographic, path, and status-code breakdowns where available.

<Tabs items={['SDK', 'REST API']} groupId="api-transport" persist>
<Tab value="SDK">

```ts
const traffic = await ship.analytics.overview("proj_123", {
  from: "2026-09-01T00:00:00Z",
  to: "2026-09-02T00:00:00Z",
});
console.log(traffic.summary, traffic.periods);
```

</Tab>
<Tab value="REST API">

```bash
curl "$OPENSHIP_URL/api/analytics/overview?projectId=proj_123&from=2026-09-01T00:00:00Z&to=2026-09-02T00:00:00Z" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"
```

</Tab>
</Tabs>

| Input | Applies to | Use |
| --- | --- | --- |
| `domain` | Summary, periods, overview, and geo | Limit results to one tracked hostname. |
| `from`, `to` | Periods, overview, and geo | Ordered ISO date range, at most 366 days. |

The project ID is required. An inaccessible or missing project is not included in results. Fixed
organization scopes do not forward through an owner's Cloud link; see [Cloud compatibility](/docs/api/sdk/compatibility#cloud).

## Read deployment statistics

<Tabs items={['SDK', 'REST API']} groupId="api-transport" persist>
<Tab value="SDK">

```ts
const stats = await ship.analytics.deploymentStats("proj_123");
console.log(stats.successfulDeployments, stats.failedDeployments);
```

</Tab>
<Tab value="REST API">

```bash
curl "$OPENSHIP_URL/api/analytics/deployments?projectId=proj_123" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"
```

</Tab>
</Tabs>

Statistics include totals, success and failure counts, average build duration, and daily counts.
`dashboard()` returns project and deployment counts for the caller's organization.

## Read runtime usage

`resources` returns an aggregate plus per-service usage, capacity, timestamp, and a `supported` flag.
`usage` and `containerInfo` read the active runtime and can return `null` when it is unavailable.

<Tabs items={['SDK', 'REST API']} groupId="api-transport" persist>
<Tab value="SDK">

```ts
const usage = await ship.analytics.resources("proj_123");
console.log(usage.supported, usage.overall, usage.services);
```

</Tab>
<Tab value="REST API">

```bash
curl "$OPENSHIP_URL/api/analytics/resources?projectId=proj_123" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"
```

</Tab>
</Tabs>

Use `usageHistory(projectId, { from, to, serviceKey })` for time buckets. All three filters are optional;
the result reports its `granularityMinutes` and selected `serviceKey`.

### Live usage

<Tabs items={['SDK', 'REST API']} groupId="api-transport" persist>
<Tab value="SDK">

```ts
for await (const event of ship.analytics.streamUsage("proj_123", {
  signal: AbortSignal.timeout(30_000),
})) {
  console.log(event);
}
```

</Tab>
<Tab value="REST API">

```bash
curl -N "$OPENSHIP_URL/api/analytics/usage/stream?projectId=proj_123" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"
```

</Tab>
</Tabs>

The REST endpoint returns Server-Sent Events. An active deployment with a running container is required.
Pass an abort signal or stop iteration to close an SDK stream.

## Control path collection

<Tabs items={['SDK', 'REST API']} groupId="api-transport" persist>
<Tab value="SDK">

```ts
await ship.analytics.setPathsCollection("proj_123", { enabled: true });
```

</Tab>
<Tab value="REST API">

```bash
curl -X POST "$OPENSHIP_URL/api/analytics/paths-collection/proj_123" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled":true}'
```

</Tab>
</Tabs>

This changes collection settings and requires write access. Other analytics methods read data.

## Server analytics

Server analytics require `server:read` access and a tracked `domain`. Persisted buckets and daily geo
data remain readable when a server is offline; live analytics require a reachable management API.

<Tabs items={['SDK', 'REST API']} groupId="api-transport" persist>
<Tab value="SDK">

```ts
const buckets = await ship.analytics.serverBuckets("srv_123", { domain: "app.example.com" });
console.log(buckets);
```

</Tab>
<Tab value="REST API">

```bash
curl "$OPENSHIP_URL/api/analytics/server/srv_123?domain=app.example.com" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"
```

</Tab>
</Tabs>

| Method | Additional input | Result |
| --- | --- | --- |
| `serverBuckets` | Optional `from`, `to` | Persisted minute buckets; range values accept ISO timestamps or epoch minutes. |
| `serverGeo` | Optional `day` in `YYYYMMDD` format | Daily country totals. |
| `serverLive` | None | Live edge analytics. |

Every method above also requires `domain`. Missing domain returns `400`; an unreachable live source can
return `502`.

## Operations

{/* api-operations:start */}

| Operation | SDK | REST API |
| --- | --- | --- |
| Stream current resource usage. | `analytics.streamUsage(projectId, options?)` | `GET /api/analytics/usage/stream`<br />`analytics:read` |
| Read summary statistics for the selected scope and period. | `analytics.summary(id, input?)` | `GET /api/analytics`<br />`analytics:read` |
| List supported analytics periods. | `analytics.periods(id, input?)` | `GET /api/analytics/periods`<br />`analytics:read` |
| Read aggregate traffic and application analytics. | `analytics.overview(id, input?)` | `GET /api/analytics/overview`<br />`analytics:read` |
| Read geographic traffic statistics. | `analytics.geo(id, input?)` | `GET /api/analytics/geo`<br />`analytics:read` |
| Read deployment outcome statistics. | `analytics.deploymentStats(id)` | `GET /api/analytics/deployments`<br />`analytics:read` |
| Read current workload resource usage. | `analytics.usage(id)` | `GET /api/analytics/usage`<br />`analytics:read` |
| Read analytics runtime/container information. | `analytics.containerInfo(id)` | `GET /api/analytics/container`<br />`analytics:read` |
| Read configured resource allocations. | `analytics.resources(id)` | `GET /api/analytics/resources`<br />`analytics:read` |
| Read historical resource usage. | `analytics.usageHistory(id, input?)` | `GET /api/analytics/usage/history`<br />`analytics:read` |
| Enable or disable request-path collection. | `analytics.setPathsCollection(id, input)` | `POST /api/analytics/paths-collection/:projectId`<br />`project:write` |
| Read server traffic buckets. | `analytics.serverBuckets(id, input)` | `GET /api/analytics/server/:serverId`<br />`server:read` |
| Read geographic server-request statistics. | `analytics.serverGeo(id, input)` | `GET /api/analytics/server/:serverId/geo`<br />`server:read` |
| Read current server traffic data. | `analytics.serverLive(id, input)` | `GET /api/analytics/server/:serverId/live`<br />`server:read` |
| Read the analytics dashboard aggregate. | `analytics.dashboard()` | `GET /api/analytics/dashboard`<br />`analytics:read` |

{/* api-operations:end */}
