# API: Packs: CPG

| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | `/v1/packs/cpg/actions` | The action list ranked by dollars: for a rep (me, a user id, or unassigned), a type and a status (open, drafted and in flight by default) | `packs:read` |
| GET | `/v1/packs/cpg/actions/:id` | One action with its evidence, the drafted email and its approval (for Approve and send) | `packs:read` |
| POST | `/v1/packs/cpg/actions/:id/dismiss` | Dismiss an action (a waiting draft is withdrawn); it stays dismissed while the data still shows it | `packs:write` |
| POST | `/v1/packs/cpg/actions/:id/draft` | Draft the email for an action to its buyer, broker or distributor rep; it waits for the rep's approval and goes from the rep's mailbox | `packs:write` |
| POST | `/v1/packs/cpg/actions/:id/reopen` | Reopen a dismissed action | `packs:write` |
| POST | `/v1/packs/cpg/actions/build` | Build the action list now (owners; it also runs every morning): new findings open, resolved ones clear, the top ones are drafted | `settings:write` |
| GET | `/v1/packs/cpg/brief` | Your morning brief (a day's: calls ranked by dollars with the ask, accounts gone quiet, short shipments, new distribution, follow-ups, stale data) | `packs:read` |
| POST | `/v1/packs/cpg/brief/run` | Write today's morning briefs now (owners; once a day per person) | `settings:write` |
| GET | `/v1/packs/cpg/category/promos` | Promo lift against each promo's own baseline | `packs:read` |
| GET | `/v1/packs/cpg/category/share` | Share vs category and private label by retailer, with the change vs the prior period and %ACV | `packs:read` |
| GET | `/v1/packs/cpg/category/velocity` | Rate of sale per store per week by retailer and SKU, with movers flagged against the 8-week baseline | `packs:read` |
| GET | `/v1/packs/cpg/dc-cover` | Days and weeks of cover per SKU per DC, the target, open POs, and the reorder in whole pallets | `packs:read` |
| GET | `/v1/packs/cpg/definitions` | The action types: what each means, its threshold (from the pack's settings), its dollar value and who it goes to | `packs:read` |
| POST | `/v1/packs/cpg/erp/sync` | Read the open orders from the connected ERP (NetSuite) now (owners) | `settings:write` |
| PATCH | `/v1/packs/cpg/feeds/:id/freshness` | Set how often a feed's source should send a file, in days (owners) | `settings:write` |
| GET | `/v1/packs/cpg/feeds/health` | Each feed's freshness: its last file and whether it's later than the source should send | `packs:read` |
| GET | `/v1/packs/cpg/fill-rates` | Fill rate by DC over the window and the one before, with the SKUs shipped short | `packs:read` |
| GET | `/v1/packs/cpg/grid` | The core-SKU coverage grid: stores × Core SKUs (Ordering or Gap), ranked by size of prize, with views by chain, distributor and rep | `packs:read` |
| GET | `/v1/packs/cpg/health` | Accounts by bucket (Active, Slowing, Dormant, Lost), each priced by what it ordered before going quiet, with the false-churn checks | `packs:read` |
| GET | `/v1/packs/cpg/mappings` | Names from each source waiting for a mapping (or decided), with candidates and confidence; cursor on (created_at, id) | `packs:read` |
| POST | `/v1/packs/cpg/mappings/:id/decide` | Decide a name (owners): approve it to a store or product, make a new record, or reject it; the rows that waited are read | `settings:write` |
| POST | `/v1/packs/cpg/mappings/:id/reopen` | Reopen a decided name (owners): later rows with it wait for a new decision | `settings:write` |
| POST | `/v1/packs/cpg/mappings/approve-confident` | Approve every waiting name whose top suggestion scores at least `min` (owners), up to 500 at a time (run it again for more) | `settings:write` |
| GET | `/v1/packs/cpg/partners` | Distributors, retailers and brokers | `packs:read` |
| GET | `/v1/packs/cpg/products` | Products (search by SKU, UPC or name) | `packs:read` |
| GET | `/v1/packs/cpg/review` | A retailer's buyer review (share, %ACV, velocity, movers, gaps, promo lift, asks): the page as JSON, or a PDF, Word file or slide outline | `packs:read` |
| GET | `/v1/packs/cpg/stores` | Stores (search by name, store number or ZIP) | `packs:read` |
| GET | `/v1/packs/cpg/stores/:id` | A store: its record, who served it when (distributor switches), the names each source uses for it, its orders and health | `packs:read` |

## Examples

### GET /v1/packs/cpg/actions

The action list ranked by dollars: for a rep (me, a user id, or unassigned), a type and a status (open, drafted and in flight by default)

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

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

### GET /v1/packs/cpg/actions/$ID

One action with its evidence, the drafted email and its approval (for Approve and send)

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

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

### POST /v1/packs/cpg/actions/$ID/dismiss

Dismiss an action (a waiting draft is withdrawn); it stays dismissed while the data still shows it

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/actions/${id}/dismiss`, {
  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/packs/cpg/actions/$ID/draft

Draft the email for an action to its buyer, broker or distributor rep; it waits for the rep's approval and goes from the rep's mailbox

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/actions/${id}/draft`, {
  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/packs/cpg/actions/$ID/reopen

Reopen a dismissed action

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/actions/${id}/reopen`, {
  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/packs/cpg/actions/build

Build the action list now (owners; it also runs every morning): new findings open, resolved ones clear, the top ones are drafted

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/actions/build`, {
  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/packs/cpg/brief

Your morning brief (a day's: calls ranked by dollars with the ask, accounts gone quiet, short shipments, new distribution, follow-ups, stale data)

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

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

### POST /v1/packs/cpg/brief/run

Write today's morning briefs now (owners; once a day per person)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/brief/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();
```

### GET /v1/packs/cpg/category/promos

Promo lift against each promo's own baseline

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

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

### GET /v1/packs/cpg/category/share

Share vs category and private label by retailer, with the change vs the prior period and %ACV

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

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

### GET /v1/packs/cpg/category/velocity

Rate of sale per store per week by retailer and SKU, with movers flagged against the 8-week baseline

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

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

### GET /v1/packs/cpg/dc-cover

Days and weeks of cover per SKU per DC, the target, open POs, and the reorder in whole pallets

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

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

### GET /v1/packs/cpg/definitions

The action types: what each means, its threshold (from the pack's settings), its dollar value and who it goes to

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

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

### POST /v1/packs/cpg/erp/sync

Read the open orders from the connected ERP (NetSuite) now (owners)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/erp/sync`, {
  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();
```

### PATCH /v1/packs/cpg/feeds/$ID/freshness

Set how often a feed's source should send a file, in days (owners)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/feeds/${id}/freshness`, {
  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/packs/cpg/feeds/health

Each feed's freshness: its last file and whether it's later than the source should send

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

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

### GET /v1/packs/cpg/fill-rates

Fill rate by DC over the window and the one before, with the SKUs shipped short

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

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

### GET /v1/packs/cpg/grid

The core-SKU coverage grid: stores × Core SKUs (Ordering or Gap), ranked by size of prize, with views by chain, distributor and rep

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

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

### GET /v1/packs/cpg/health

Accounts by bucket (Active, Slowing, Dormant, Lost), each priced by what it ordered before going quiet, with the false-churn checks

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

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

### GET /v1/packs/cpg/mappings

Names from each source waiting for a mapping (or decided), with candidates and confidence; cursor on (created_at, id)

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

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

### POST /v1/packs/cpg/mappings/$ID/decide

Decide a name (owners): approve it to a store or product, make a new record, or reject it; the rows that waited are read

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/mappings/${id}/decide`, {
  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/packs/cpg/mappings/$ID/reopen

Reopen a decided name (owners): later rows with it wait for a new decision

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/mappings/${id}/reopen`, {
  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/packs/cpg/mappings/approve-confident

Approve every waiting name whose top suggestion scores at least `min` (owners), up to 500 at a time (run it again for more)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/mappings/approve-confident`, {
  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/packs/cpg/partners

Distributors, retailers and brokers

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

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

### GET /v1/packs/cpg/products

Products (search by SKU, UPC or name)

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

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

### GET /v1/packs/cpg/review

A retailer's buyer review (share, %ACV, velocity, movers, gaps, promo lift, asks): the page as JSON, or a PDF, Word file or slide outline

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

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

### GET /v1/packs/cpg/stores

Stores (search by name, store number or ZIP)

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

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

### GET /v1/packs/cpg/stores/$ID

A store: its record, who served it when (distributor switches), the names each source uses for it, its orders and health

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

```js
const res = await fetch(`https://api.closefinch.com/v1/packs/cpg/stores/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
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).
