# Send batches of services

> How to create and update batches of services from your system, and how to handle errors.

Canonical URL: https://apis.cortecloud.com.br/docs/en/guias/integracao-erp/lotes/

A **batch** groups the service center's [services](https://apis.cortecloud.com.br/docs/en/comecando/conceitos.md#servico) for production. Your integration builds the batch in your system and sends it to Cortecloud, which stores the grouping and shows it to production and to PCP. A service can be in several batches, and the batch does not change the service.

Two routes, both require service-center authentication ([HMAC](https://apis.cortecloud.com.br/docs/en/comecando/autenticacao.md)):

| Route | Use |
|---|---|
| [`POST /batches`](https://apis.cortecloud.com.br/docs/swagger#/Batches/createBatch) | Creates the batch and returns its `id`. |
| [`PUT /batches/{id}`](https://apis.cortecloud.com.br/docs/swagger#/Batches/updateBatch) | Updates the batch by `id`. |

## Create a batch {#criar-um-lote}

```json
{
  "internal_code": "LOTE-0042",
  "description": "Morning shift",
  "services": [
    { "id": 1234 },
    { "internal_code": "PED-000123" }
  ]
}
```

- `internal_code` is the batch code in your system and is required. It cannot repeat within the service center.
- `description` is optional.
- `services` is required on creation, with 1 to 100 services per request.
- Each service is identified by `id` or by `internal_code`; sending both on the same service is rejected with `400`.

The `201` response carries the batch `id`. **Keep it**: the update requires this `id`.

## Update a batch {#atualizar-um-lote}

Only the fields sent change, and you must send at least one:

| Field | Effect |
|---|---|
| `internal_code` | Changes the batch code. Absent keeps it. |
| `description` | Changes the description. Absent keeps it; `null` clears it. |
| `services` | Replaces the whole list: services left out are removed from the batch, and `[]` empties it. Absent keeps the services. |

```json
{ "services": [{ "id": 1234 }, { "id": 1235 }] }
```

The update overwrites edits made in Cortecloud. Repeating the same call does not change the result.

## Which services are accepted {#quais-servicos-entram}

The service must be produced at the request's service center and released to production (status `7`, `13`, `21` or `22`). A finished (`9`) or not yet released service is rejected.

A service `internal_code` that matches more than one of the center's services is ambiguous, and the whole batch is rejected. In that case, send the `id`. The lookup covers services in every status, so an old service with the same code also causes ambiguity.

## Errors {#erros}

| Status | When |
|---|---|
| `400` | Malformed body: no `internal_code` or no `services` on creation, empty body on update, a service with neither `id` nor `internal_code` or with both, more than 100 services. |
| `404` | On update, batch does not exist or belongs to another service center. |
| `409` | A batch with this `internal_code` already exists at the service center. |
| `422` | Some service cannot be part of the batch. |

On `422`, the `problems` field lists each rejected service and the reason:

```json
{
  "status": 422,
  "problems": [
    { "ref": { "id": 1234 }, "reason": "finished" },
    { "ref": { "internalCode": "PED-000123" }, "reason": "ambiguous" }
  ]
}
```

| `reason` | Meaning |
|---|---|
| `not_found` | Service does not exist or belongs to another service center. |
| `ambiguous` | `internal_code` matches more than one service; send the `id`. |
| `finished` | Service is finished. |
| `not_released` | Service is not yet released to production. |
| `duplicated` | Service repeated in the list. |

A batch with a rejected service is neither created nor changed.

:::caution Lost response on creation
If the `POST` response is lost, a retry receives `409` without the batch `id`. In that case, contact support to recover it.
:::
