---
title: Nesting
description: The Nesting API reads your organization's sheet-nesting potential over the last 90 days and how many job-nest runs this month's allowance has used and left.
---

# Nesting

The Nesting API reads your organization's sheet-nesting potential over the last 90 days and how many job-nest runs this month's allowance has used and left.

> **Auto-generated** from the public OpenAPI spec — this page never
> drifts from the running API. Base URL `https://api.arcnm.io`. Authenticate with
> the `X-API-Key` header (see [Authentication](../authentication.md)).

## What nesting orders together would save, last 90 days

`GET /api/v1/nesting/potential`

The organization's sheet quotes in the fixed 90-day window.

**Request**

<CodeTabs>

```bash title="cURL"
curl -X GET https://api.arcnm.io/api/v1/nesting/potential \
  -H "X-API-Key: $ARCNM_API_KEY"
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/nesting/potential",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/nesting/potential", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `addon` | boolean | Whether the organization has the Nesting add-on. |
| `combining_basis` | string |  |
| `combining_bound` | string |  |
| `count` | integer | Sheet quotes in the window the figure reads. |
| `currency` | string |  |
| `saving_eur_min` | number | A lower bound on nesting the quotes' leftover copies together on shared sheets, against each part on its own sheet as its quote priced it. Without the Nesting add-on it is floored to steps of 10 EUR, from five quotes on, and 0 below that. |
| `window_days` | integer |  |
| `window_end` | string | Last UTC date of the window, inclusive. |
| `window_start` | string | First UTC date of the window, inclusive. |

**Example response**

```json
{
  "addon": true,
  "combining_basis": "compared_with_each_part_alone",
  "combining_bound": "at_least",
  "count": 0,
  "currency": "EUR",
  "saving_eur_min": 0,
  "window_days": 0,
  "window_end": "string",
  "window_start": "string"
}
```

## What nesting a selection together would save

`POST /api/v1/nesting/potential`

The same figure, limited to the given quotes. Needs the Nesting add-on.

**Request body** (`application/json`)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `calculation_ids` | string[] | yes | Sheet quotes to include. Rows the caller cannot read are absent. |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X POST https://api.arcnm.io/api/v1/nesting/potential \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "calculation_ids": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  }'
```

```python title="Python"
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/nesting/potential",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "calculation_ids": [
            "3fa85f64-5717-4562-b3fc-2c963f66afa6"
        ]
    },
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/nesting/potential", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "calculation_ids": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  }),
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `409` | `conflict` | A conflicting change, or an `Idempotency-Key` reused with a different body. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `addon` | boolean | Whether the organization has the Nesting add-on. |
| `combining_basis` | string |  |
| `combining_bound` | string |  |
| `count` | integer | Sheet quotes in the window the figure reads. |
| `currency` | string |  |
| `saving_eur_min` | number | A lower bound on nesting the quotes' leftover copies together on shared sheets, against each part on its own sheet as its quote priced it. Without the Nesting add-on it is floored to steps of 10 EUR, from five quotes on, and 0 below that. |
| `window_days` | integer |  |
| `window_end` | string | Last UTC date of the window, inclusive. |
| `window_start` | string | First UTC date of the window, inclusive. |

**Example response**

```json
{
  "addon": true,
  "combining_basis": "compared_with_each_part_alone",
  "combining_bound": "at_least",
  "count": 0,
  "currency": "EUR",
  "saving_eur_min": 0,
  "window_days": 0,
  "window_end": "string",
  "window_start": "string"
}
```

## Nesting runs used and remaining

`GET /api/v1/nesting/runs`

How many nesting runs this organization has used in the current window, and how many remain.

The count is this organization's own. It is not a price and it carries no layout.
Without the Nesting add-on no run is included, and both the allowance and what
remains of it are 0.

**Request**

<CodeTabs>

```bash title="cURL"
curl -X GET https://api.arcnm.io/api/v1/nesting/runs \
  -H "X-API-Key: $ARCNM_API_KEY"
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/nesting/runs",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/nesting/runs", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `runs_left` | integer | Nesting runs still available in the current window. 0 without the Nesting add-on. |
| `runs_per_month` | integer | Nesting runs included in the current window. 0 without the Nesting add-on: no run starts without it. |
| `runs_reset_on` | string | UTC date the next window starts and the runs are available again. Windows are monthly, also on an annual plan. |
| `runs_used` | integer | Nesting runs already used in the current window. |

**Example response**

```json
{
  "runs_left": 0,
  "runs_per_month": 0,
  "runs_reset_on": "string",
  "runs_used": 0
}
```
