# API: Analytics

| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | `/v1/analytics-exports` | Your exports (the last 20) | `search:read` |
| POST | `/v1/analytics-exports` | Export a dataset (CSV or NDJSON) or a view, gzipped, as you see the data; or the analysis pack (owners): every dataset plus a README.md data dictionary. Ready within minutes; kept 24 hours | `search:read` |
| GET | `/v1/analytics-exports/:id` | One of your exports, with its download link once it's ready (signed, until it expires) | `search:read` |
| GET | `/v1/analytics/catalog` | The semantic layer: every dataset, its fields (dimensions) and measures, for building view specs | `search:read` |
| GET | `/v1/analytics/dictionary` | The data dictionary (Markdown): every dataset and column, as in the analysis pack's README.md | `search:read` |
| GET | `/v1/attribution` | Attribution of meetings, opportunities, pipeline and closed-won revenue to touchpoints (by channel, kind, UTM source or campaign) under a model: w_shaped (default), u_shaped, first_touch, last_touch, linear, time_decay; 90-day lookback | `search:read` |
| DELETE | `/v1/dashboard-email-optouts/:ownerId` | Take back stopping someone's dashboard emails (so they can add you again) | `search:read` |
| GET | `/v1/dashboard-schedules` | Dashboard emails you set up (owners: all) | `search:read` |
| POST | `/v1/dashboard-schedules` | Email a dashboard on days of the week at a local time (IANA time zone) to members; each email reruns its views as each recipient and shows the change since their last one | `records:write` |
| DELETE | `/v1/dashboard-schedules/:id` | Stop and delete a dashboard email | `records:write` |
| PATCH | `/v1/dashboard-schedules/:id` | Change, pause (status paused) or resume (status active) a dashboard email | `records:write` |
| POST | `/v1/dashboard-schedules/:id/leave` | Stop getting a dashboard email you receive (any recipient) | `search:read` |
| GET | `/v1/dashboards` | Your dashboards and those shared with the organization | `search:read` |
| POST | `/v1/dashboards` | Save a dashboard: views (specs, or analyses with their code), private or shared with the organization (each viewer still sees only what they may) | `records:write` |
| DELETE | `/v1/dashboards/:id` | Delete a dashboard and its email schedules (its owner, or an organization owner) | `records:write` |
| GET | `/v1/dashboards/:id` | A dashboard's definition | `search:read` |
| PATCH | `/v1/dashboards/:id` | Change a dashboard (its owner, or an organization owner) | `records:write` |
| GET | `/v1/dashboards/:id/run` | Run a dashboard's views as you see the data (analyses in the sandbox) | `search:read` |
| GET | `/v1/datasets/:dataset/rows` | A dataset's rows (every field), in pages with a cursor, as you see the data | `search:read` |
| GET | `/v1/live/calls` | Calls in progress: people's dialer and desk calls, voice agents' calls with their live transcript (owners), and meetings a bot is in; for owners and the callers' managers | `calls:read` |
| PUT | `/v1/members/:userId/region` | Set a member's region for the team view (owners); null clears it | `members:write` |
| GET | `/v1/team-view` | Bookings, win rate, pipeline created, meetings held, activities and focus by rep, team or region, for a period (YYYY-MM or FYyyyy-Qn, with quotas and attainment) or a date range | `search:read` |
| POST | `/v1/views/analysis` | Rerun an analysis (its view spec and code) in the sandbox, as you see the data | `records:write` |
| POST | `/v1/views/analyze` | An analysis a view spec can't express: the model writes a view spec and JavaScript that runs in the sandbox (no network) over the rows you may see, returning a table, a chart or a text; the code comes back to save on a dashboard | `records:write` |
| POST | `/v1/views/ask` | Ask a question in plain English: the model writes a view spec over the semantic layer (never SQL), which is checked and run as you see the data | `search:read` |
| POST | `/v1/views/run` | Run a view spec (dataset, measures, dimensions, filters, time grain, sort, limit, chart) as you see the data; format csv returns the same rows as CSV text | `search:read` |

## Examples

### GET /v1/analytics-exports

Your exports (the last 20)

```bash
curl -s "https://api.closefinch.com/v1/analytics-exports" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/analytics-exports`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/analytics-exports

Export a dataset (CSV or NDJSON) or a view, gzipped, as you see the data; or the analysis pack (owners): every dataset plus a README.md data dictionary. Ready within minutes; kept 24 hours

```bash
curl -s -X POST "https://api.closefinch.com/v1/analytics-exports" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/analytics-exports`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/analytics-exports/$ID

One of your exports, with its download link once it's ready (signed, until it expires)

```bash
curl -s "https://api.closefinch.com/v1/analytics-exports/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/analytics-exports/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/analytics/catalog

The semantic layer: every dataset, its fields (dimensions) and measures, for building view specs

```bash
curl -s "https://api.closefinch.com/v1/analytics/catalog" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/analytics/catalog`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/analytics/dictionary

The data dictionary (Markdown): every dataset and column, as in the analysis pack's README.md

```bash
curl -s "https://api.closefinch.com/v1/analytics/dictionary" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/analytics/dictionary`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/attribution

Attribution of meetings, opportunities, pipeline and closed-won revenue to touchpoints (by channel, kind, UTM source or campaign) under a model: w_shaped (default), u_shaped, first_touch, last_touch, linear, time_decay; 90-day lookback

```bash
curl -s "https://api.closefinch.com/v1/attribution" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/attribution`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### DELETE /v1/dashboard-email-optouts/$OWNER_ID

Take back stopping someone's dashboard emails (so they can add you again)

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/dashboard-email-optouts/$OWNER_ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboard-email-optouts/${ownerId}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/dashboard-schedules

Dashboard emails you set up (owners: all)

```bash
curl -s "https://api.closefinch.com/v1/dashboard-schedules" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboard-schedules`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/dashboard-schedules

Email a dashboard on days of the week at a local time (IANA time zone) to members; each email reruns its views as each recipient and shows the change since their last one

```bash
curl -s -X POST "https://api.closefinch.com/v1/dashboard-schedules" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboard-schedules`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### DELETE /v1/dashboard-schedules/$ID

Stop and delete a dashboard email

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/dashboard-schedules/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboard-schedules/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PATCH /v1/dashboard-schedules/$ID

Change, pause (status paused) or resume (status active) a dashboard email

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/dashboard-schedules/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboard-schedules/${id}`, {
  method: "PATCH",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/dashboard-schedules/$ID/leave

Stop getting a dashboard email you receive (any recipient)

```bash
curl -s -X POST "https://api.closefinch.com/v1/dashboard-schedules/$ID/leave" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboard-schedules/${id}/leave`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/dashboards

Your dashboards and those shared with the organization

```bash
curl -s "https://api.closefinch.com/v1/dashboards" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboards`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/dashboards

Save a dashboard: views (specs, or analyses with their code), private or shared with the organization (each viewer still sees only what they may)

```bash
curl -s -X POST "https://api.closefinch.com/v1/dashboards" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboards`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### DELETE /v1/dashboards/$ID

Delete a dashboard and its email schedules (its owner, or an organization owner)

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/dashboards/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboards/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/dashboards/$ID

A dashboard's definition

```bash
curl -s "https://api.closefinch.com/v1/dashboards/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboards/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PATCH /v1/dashboards/$ID

Change a dashboard (its owner, or an organization owner)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/dashboards/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboards/${id}`, {
  method: "PATCH",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/dashboards/$ID/run

Run a dashboard's views as you see the data (analyses in the sandbox)

```bash
curl -s "https://api.closefinch.com/v1/dashboards/$ID/run" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/dashboards/${id}/run`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/datasets/$DATASET/rows

A dataset's rows (every field), in pages with a cursor, as you see the data

```bash
curl -s "https://api.closefinch.com/v1/datasets/$DATASET/rows" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/datasets/${dataset}/rows`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/live/calls

Calls in progress: people's dialer and desk calls, voice agents' calls with their live transcript (owners), and meetings a bot is in; for owners and the callers' managers

```bash
curl -s "https://api.closefinch.com/v1/live/calls" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/live/calls`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PUT /v1/members/$USER_ID/region

Set a member's region for the team view (owners); null clears it

```bash
curl -s -X PUT "https://api.closefinch.com/v1/members/$USER_ID/region" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/members/${userId}/region`, {
  method: "PUT",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/team-view

Bookings, win rate, pipeline created, meetings held, activities and focus by rep, team or region, for a period (YYYY-MM or FYyyyy-Qn, with quotas and attainment) or a date range

```bash
curl -s "https://api.closefinch.com/v1/team-view" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/team-view`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/views/analysis

Rerun an analysis (its view spec and code) in the sandbox, as you see the data

```bash
curl -s -X POST "https://api.closefinch.com/v1/views/analysis" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/views/analysis`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/views/analyze

An analysis a view spec can't express: the model writes a view spec and JavaScript that runs in the sandbox (no network) over the rows you may see, returning a table, a chart or a text; the code comes back to save on a dashboard

```bash
curl -s -X POST "https://api.closefinch.com/v1/views/analyze" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/views/analyze`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/views/ask

Ask a question in plain English: the model writes a view spec over the semantic layer (never SQL), which is checked and run as you see the data

```bash
curl -s -X POST "https://api.closefinch.com/v1/views/ask" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/views/ask`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/views/run

Run a view spec (dataset, measures, dimensions, filters, time grain, sort, limit, chart) as you see the data; format csv returns the same rows as CSV text

```bash
curl -s -X POST "https://api.closefinch.com/v1/views/run" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/views/run`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

Request and response schemas: [https://www.closefinch.com/openapi.json](https://www.closefinch.com/openapi.json). All resources: [API reference](https://www.closefinch.com/docs/api).
