API reference
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)
curl -s "https://api.closefinch.com/v1/packs/cpg/actions" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/packs/cpg/actions/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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
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 '{}'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
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 '{}'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
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 '{}'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
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 '{}'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)
curl -s "https://api.closefinch.com/v1/packs/cpg/brief" \
-H "Authorization: Bearer $RA_API_KEY"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)
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 '{}'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
curl -s "https://api.closefinch.com/v1/packs/cpg/category/promos" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/category/share" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/category/velocity" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/dc-cover" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/definitions" \
-H "Authorization: Bearer $RA_API_KEY"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)
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 '{}'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)
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 '{}'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
curl -s "https://api.closefinch.com/v1/packs/cpg/feeds/health" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/fill-rates" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/grid" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/health" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/packs/cpg/mappings" \
-H "Authorization: Bearer $RA_API_KEY"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
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 '{}'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
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 '{}'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)
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 '{}'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
curl -s "https://api.closefinch.com/v1/packs/cpg/partners" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/packs/cpg/products" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/review" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s "https://api.closefinch.com/v1/packs/cpg/stores" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/packs/cpg/stores/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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. All resources: API reference.