# Save a set of status changes

```http
POST https://secure.yoprint.com/v1/api/store/{team_slug}/setting/status/{status_reference}
```

- API version: v1
- Operation ID: `v1_public_status_sync`
- Section: Team settings › [Statuses](https://developer.yoprint.com/reference/statuses.md)
- Web page: https://developer.yoprint.com/reference/statuses/v1-status-sync/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Creates, updates and deletes several statuses in one request, all or nothing. This is how the web app saves the status settings page, and the only way to move a list's start or end marker.

Call it as `POST /v1/api/store/{team_slug}/setting/status/sync`: the last path segment must be the word `sync`. Any other word answers 405.

Send `data`, a list of changes, each with an `action`:

- `create`: a new status. Needs `label`, `color`, `role`, `type` (`in_progress` or `end`) and `position`.
- `update`: an existing status, by `id`. Send `position` and what changes. Unlike the single update, it can change `type`.
- `delete`: an `in_progress` status, by `id`.

Returns every status of the team, including deleted ones, like the full list.

## Permission

Needs the Manage Settings permission. The team owner always has it.

## Business rules

- All changes run in one transaction: if one fails, none is saved.
- Updating a status to `type: start` or `end` turns the list's current start or end status into `in_progress`, so each list keeps one of each.
- A `start` or `end` status can't be changed to another type directly. Mark another status as start or end instead.
- `delete` works only on `in_progress` statuses; any other type fails the whole request with 500.
- `create` accepts only `type` `in_progress` or `end`; `start` and `pre_production` fail the whole request with 500. A created `end` status does not demote the existing one.
- Task statuses (`role: pipeline`): this call doesn't decode `pipeline_id`, so a task status created here belongs to no task preset, and an `update` that sends `pipeline_id` detaches it from its preset. Use "Create a status" and "Update a status" for task statuses.

## Side effects

- Team members who have YoPrint open see each change at once.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.
- `status_reference` (string, required): Always the word `sync`. Any other value answers 405. One of: `"sync"`. Example `sync`.

## Request body

Content type `application/json`, required.

Fields:

- `data` (array of objects, required): At least 1 item.
  - Each item:
    - `action` (string, required): One of: `"create"`, `"update"`, `"delete"`.
    - `color` (string, optional): A hex color with the `#`, 3 or 6 digits: `#1e88e5`. Matches `^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$`.
    - `customer_label` (string, optional)
    - `id` (string, optional): Required for `update` and `delete`: the status to change.
    - `label` (string, optional): Required for `create`.
    - `pipeline_id` (string, optional): Do not send. This operation does not link statuses to task presets. To create task statuses (`role: pipeline`), use Create a status instead.
    - `position` (integer, optional): Required for `create` and `update`. Minimum -2147483648. Maximum 2147483647.
    - `role` (string, optional): Required for `create`. Which status list it belongs to (`order`, `quote`, `job`, `purchase_order`, `pipeline`, or `shipment`). `customer_message` statuses cannot be created here, and task statuses (`pipeline`) should be created with Create a status instead. One of: `"order"`, `"quote"`, `"job"`, `"purchase_order"`, `"pipeline"`, `"shipment"`.
    - `type` (string, optional): Required for `create`, which accepts `in_progress` or `end`. On `update`, setting `start` or `end` moves that stage marker to this status; see the rules. One of: `"start"`, `"pre_production"`, `"in_progress"`, `"end"`.

### Example request

```bash
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/setting/status/sync' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "data": [
      {
        "action": "create",
        "color": "#43a047",
        "label": "Ready for pickup",
        "position": 5,
        "role": "order",
        "type": "in_progress"
      },
      {
        "action": "update",
        "id": "0CoeFF1BmpcxxE",
        "position": 6,
        "type": "end"
      },
      {
        "action": "delete",
        "id": "bMlYH975FRUWEr"
      }
    ]
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (array of objects, required)
  - Each item:
    - `color` (string, required)
    - `customer_label` (string, required): What customers see in the customer portal. When none is set: `Pending` for `start`, `In Progress` for `in_progress` and `pre_production`, `Completed` for `end`.
    - `id` (string, required)
    - `label` (string, required)
    - `position` (integer, required): Sort order within the list, lowest first.
    - `role` (string, required): Which list the status belongs to: - `order`: sales orders - `quote`: quotes - `job`: jobs - `purchase_order`: purchase orders - `shipment`: shipments - `customer_message`: message threads - `pipeline`: tasks within a task preset One of: `"order"`, `"quote"`, `"job"`, `"purchase_order"`, `"shipment"`, `"customer_message"`, `"pipeline"`.
    - `trashed` (boolean, required): True for a deleted status. Only the full list includes deleted ones.
    - `type` (string, required): The stage of the status in the workflow: `start` (first status in the list), `pre_production`, `in_progress`, or `end` (final status). One of: `"start"`, `"pre_production"`, `"in_progress"`, `"end"`.
    - `pipeline_id` (string, optional): The task preset, for `pipeline` statuses only. Absent for every other role.
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": [
    {
      "color": "#f5f5f5",
      "customer_label": "Pending",
      "id": "q0hnLYYLRQE3tw",
      "label": "New",
      "position": 0,
      "role": "order",
      "trashed": false,
      "type": "start"
    },
    {
      "color": "#1e88e5",
      "customer_label": "Completed",
      "id": "0CoeFF1BmpcxxE",
      "label": "Printing",
      "position": 6,
      "role": "order",
      "trashed": false,
      "type": "end"
    },
    {
      "color": "#424242",
      "customer_label": "In Progress",
      "id": "FDIbFjrYvFgaCW",
      "label": "Completed",
      "position": 6,
      "role": "order",
      "trashed": false,
      "type": "in_progress"
    },
    {
      "color": "#8e24aa",
      "customer_label": "In Progress",
      "id": "bMlYH975FRUWEr",
      "label": "Quality check",
      "position": 3,
      "role": "order",
      "trashed": true,
      "type": "in_progress"
    },
    {
      "color": "#43a047",
      "customer_label": "In Progress",
      "id": "Why7b1DdlX6iuu",
      "label": "Ready for pickup",
      "position": 5,
      "role": "order",
      "trashed": false,
      "type": "in_progress"
    }
  ],
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
  - When: Your role lacks Manage Settings. The body is `{"message": "Insufficient Permission"}`, without the error envelope. Fix: Use the key of a member whose role has Manage Settings, or the owner's.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
  - When: An `update` or `delete` id is not one of your team's statuses. Fix: Use ids from the full list.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: `data` is empty, an item has no `action`, or a `create` item misses a required field (`validation_failed`). Fix: Send at least one change, each with its `action` and the fields that action needs.
- `500` A business rule refused the request (see the operation's errors), or something failed inside YoPrint. Refusals use the error envelope with a code such as `action_not_allowed`; an unexpected failure answers `{"message": "Server Error"}`. Repeating a refusal gets the same answer; after an unexpected failure, read the record back before you retry a change.
  - When: A `delete` targets a status that is not `in_progress`, a `create` has the wrong `type`, or a `start`/`end` status is updated to another type. The body is `{"message": "Server Error"}`, without the error envelope. Fix: Follow the rules above. Nothing was saved.

## Related

- [List every status, including deleted ones](https://developer.yoprint.com/reference/statuses/v1-status-index.md): `GET /v1/api/store/{team_slug}/setting/status`
- [Create a status](https://developer.yoprint.com/reference/statuses/v1-status-store.md): `POST /v1/api/store/{team_slug}/setting/status`
- [Update a status without checks](https://developer.yoprint.com/reference/statuses/v1-status-update-patch.md): `PATCH /v1/api/store/{team_slug}/setting/status/{status_reference}`
