# API: Forecasting

| Method | Path | What it does | Scope |
|---|---|---|---|
| POST | `/v1/capacity` | Capacity for a period from quotas, ramps and expected attainment, with hiring what-ifs (owners: everyone; managers: their reports; others: themselves) | `deals:read` |
| POST | `/v1/deals/:id/commit-test` | Run the commit test on a deal: six conditions, each from evidence in the buyer's own words | `deals:write` |
| POST | `/v1/deals/:id/forecast-assessment` | Estimate a deal's likelihood and expected close date from its evidence | `deals:write` |
| PUT | `/v1/deals/:id/forecast-category` | Set a deal's forecast category (its owner, or an org owner) with a reason; null clears it. Closed comes only from winning the deal | `deals:write` |
| GET | `/v1/forecast` | The forecast for a period at a level (you, someone below you, a team, or the org): roll-up, adjustments, range, flags, the AI forecast | `deals:read` |
| GET | `/v1/forecast/accuracy` | A period's calls against what was won (the last period by default): by person, the org and size, with the direction of the miss and up to three fixes | `deals:read` |
| GET | `/v1/forecast/adjustments` | Every adjustment for a period at a level (history) | `deals:read` |
| POST | `/v1/forecast/adjustments` | Adjust your level's number (a manager) or the org's (an owner), with a reason; deal data and people's own numbers don't change | `deals:write` |
| GET | `/v1/forecast/digest` | Your weekly pipeline digest now (and the forecast brief, for owners) | `deals:read` |
| POST | `/v1/forecast/run` | Queue the weekly forecast pass now: commit tests, likelihoods, a snapshot (owner) | `settings:write` |
| GET | `/v1/forecast/scenarios` | Saved scenarios, with their inputs and results (owner) | `deals:read` |
| POST | `/v1/forecast/scenarios` | Run a what-if on the org's forecast (win rates, slippage, deals in or out, pipeline creation, a macro factor); give a name to save it (owner) | `settings:write` |
| GET | `/v1/forecast/snapshots` | Snapshots for a period, newest first (owner) | `deals:read` |
| POST | `/v1/forecast/snapshots` | Take a pipeline snapshot now (owner; one an hour) | `settings:write` |
| GET | `/v1/forecast/snapshots/:id/changes` | What changed since a snapshot, or between two (owners: everything; others: their own deals) | `deals:read` |
| GET | `/v1/forecast/submissions` | Submissions for a period (yours and the people below you; owners: everyone) | `deals:read` |
| POST | `/v1/forecast/submissions` | Submit your call for a period (commit and best case); a manager's is their roll-up call | `deals:write` |
| PUT | `/v1/members/:id/ramp` | Set a rep's start date and ramp (owner; capacity planning) | `members:write` |
| GET | `/v1/pipeline/dollars` | $ at risk and $ opportunity, with the deals behind them (owners: the org; others: theirs and their reports') | `deals:read` |
| GET | `/v1/pipeline/metrics` | Coverage, slipped deals, days in stage, win rates by stage/owner/size, ARR new vs expansion vs renewal, with formulas (owner) | `deals:read` |
| PUT | `/v1/quotas` | Set a rep's quota for a period (owner) | `settings:write` |
| GET | `/v1/settings/forecast` | How the org forecasts: fiscal year, period, targets, digests | `deals:read` |
| PUT | `/v1/settings/forecast` | Set how the org forecasts (owner) | `settings:write` |
| PUT | `/v1/stages/:id/forecast-category` | Set a stage's forecast category (owner); null derives it from the stage's type and probability | `settings:write` |
| GET | `/v1/teams` | Teams and their members | `deals:read` |
| POST | `/v1/teams` | Create a team (owner) | `settings:write` |
| PUT | `/v1/teams/:id` | Change a team (owner) | `settings:write` |
| GET | `/v1/territories` | Territories, their rules and owners, and (owners) the balance per owner | `deals:read` |
| POST | `/v1/territories` | Create a territory (owner) | `settings:write` |
| PUT | `/v1/territories/:id` | Change a territory (owner) | `settings:write` |
| POST | `/v1/territories/draft` | Draft a territory from plain English (nothing is saved) | `settings:write` |
| POST | `/v1/territories/plan` | Find accounts and leads outside their territory's owners and propose reassignments (owner) | `settings:write` |
| GET | `/v1/territory-proposals` | Open reassignment proposals (owner) | `deals:read` |
| POST | `/v1/territory-proposals/:id/:decision` | Accept (the owner changes) or dismiss a reassignment (owner) | `settings:write` |

## Examples

### POST /v1/capacity

Capacity for a period from quotas, ramps and expected attainment, with hiring what-ifs (owners: everyone; managers: their reports; others: themselves)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/capacity`, {
  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/deals/$ID/commit-test

Run the commit test on a deal: six conditions, each from evidence in the buyer's own words

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

```js
const res = await fetch(`https://api.closefinch.com/v1/deals/${id}/commit-test`, {
  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/deals/$ID/forecast-assessment

Estimate a deal's likelihood and expected close date from its evidence

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

```js
const res = await fetch(`https://api.closefinch.com/v1/deals/${id}/forecast-assessment`, {
  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();
```

### PUT /v1/deals/$ID/forecast-category

Set a deal's forecast category (its owner, or an org owner) with a reason; null clears it. Closed comes only from winning the deal

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

```js
const res = await fetch(`https://api.closefinch.com/v1/deals/${id}/forecast-category`, {
  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/forecast

The forecast for a period at a level (you, someone below you, a team, or the org): roll-up, adjustments, range, flags, the AI forecast

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

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

### GET /v1/forecast/accuracy

A period's calls against what was won (the last period by default): by person, the org and size, with the direction of the miss and up to three fixes

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

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

### GET /v1/forecast/adjustments

Every adjustment for a period at a level (history)

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

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

### POST /v1/forecast/adjustments

Adjust your level's number (a manager) or the org's (an owner), with a reason; deal data and people's own numbers don't change

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

```js
const res = await fetch(`https://api.closefinch.com/v1/forecast/adjustments`, {
  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/forecast/digest

Your weekly pipeline digest now (and the forecast brief, for owners)

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

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

### POST /v1/forecast/run

Queue the weekly forecast pass now: commit tests, likelihoods, a snapshot (owner)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/forecast/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/forecast/scenarios

Saved scenarios, with their inputs and results (owner)

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

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

### POST /v1/forecast/scenarios

Run a what-if on the org's forecast (win rates, slippage, deals in or out, pipeline creation, a macro factor); give a name to save it (owner)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/forecast/scenarios`, {
  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/forecast/snapshots

Snapshots for a period, newest first (owner)

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

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

### POST /v1/forecast/snapshots

Take a pipeline snapshot now (owner; one an hour)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/forecast/snapshots`, {
  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/forecast/snapshots/$ID/changes

What changed since a snapshot, or between two (owners: everything; others: their own deals)

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

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

### GET /v1/forecast/submissions

Submissions for a period (yours and the people below you; owners: everyone)

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

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

### POST /v1/forecast/submissions

Submit your call for a period (commit and best case); a manager's is their roll-up call

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

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

### PUT /v1/members/$ID/ramp

Set a rep's start date and ramp (owner; capacity planning)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/members/${id}/ramp`, {
  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/pipeline/dollars

$ at risk and $ opportunity, with the deals behind them (owners: the org; others: theirs and their reports')

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

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

### GET /v1/pipeline/metrics

Coverage, slipped deals, days in stage, win rates by stage/owner/size, ARR new vs expansion vs renewal, with formulas (owner)

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

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

### PUT /v1/quotas

Set a rep's quota for a period (owner)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/quotas`, {
  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/settings/forecast

How the org forecasts: fiscal year, period, targets, digests

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

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

### PUT /v1/settings/forecast

Set how the org forecasts (owner)

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

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

### PUT /v1/stages/$ID/forecast-category

Set a stage's forecast category (owner); null derives it from the stage's type and probability

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

```js
const res = await fetch(`https://api.closefinch.com/v1/stages/${id}/forecast-category`, {
  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/teams

Teams and their members

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

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

### POST /v1/teams

Create a team (owner)

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

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

### PUT /v1/teams/$ID

Change a team (owner)

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

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

Territories, their rules and owners, and (owners) the balance per owner

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

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

### POST /v1/territories

Create a territory (owner)

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

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

### PUT /v1/territories/$ID

Change a territory (owner)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/territories/${id}`, {
  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();
```

### POST /v1/territories/draft

Draft a territory from plain English (nothing is saved)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/territories/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/territories/plan

Find accounts and leads outside their territory's owners and propose reassignments (owner)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/territories/plan`, {
  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/territory-proposals

Open reassignment proposals (owner)

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

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

### POST /v1/territory-proposals/$ID/$DECISION

Accept (the owner changes) or dismiss a reassignment (owner)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/territory-proposals/${id}/${decision}`, {
  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).
