# Create services

> How to create a service with parts from your system, send it to optimization and follow the result by webhook.

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

Your integration can create a [service](https://apis.cortecloud.com.br/docs/en/comecando/conceitos.md#servico) at the service center with the parts already defined in your system. Cortecloud registers the carpenter, fills in the parts, sends the service to optimization and generates the quote, as with a service created in the app.

Route: [`POST /services`](https://apis.cortecloud.com.br/docs/swagger#/Services/createService). Requires service-center authentication ([HMAC](https://apis.cortecloud.com.br/docs/en/comecando/autenticacao.md)); with Basic authentication, it responds with `401`.

## Body {#corpo}

```json
{
  "serviceInternalCode": "PED-123",
  "productionInternalCode": "LINHA-1",
  "carpenterEmail": "carpenter@example.com",
  "carpenterName": "John Carpenter",
  "carpenterInternalCode": "CLI-9",
  "parts": [
    {
      "quantity": 1,
      "c": 500,
      "l": 500,
      "function": "Lateral",
      "complement": "Balcao A",
      "client": "Ana",
      "furniture": "Kitchen",
      "material": { "internalCode": "MDF18BR" },
      "c1": { "internalCode": "FT04BR" },
      "c2": null,
      "l1": null,
      "l2": null,
      "machining": {
        "x": 500,
        "y": 500,
        "z": 18,
        "startSide": 0,
        "horizontalDrills": [],
        "verticalDrills": [
          { "corner": 0, "bolthole": false, "x": 25, "y": 37, "depth": 12, "diameter": 15, "face": "i" }
        ],
        "furrowMachining": null,
        "furrowMachiningPair": null
      }
    }
  ]
}
```

| Field | Rule |
| --- | --- |
| `serviceInternalCode` | The service's [internal code](https://apis.cortecloud.com.br/docs/en/comecando/conceitos.md#codigo-interno), usually the order number in the ERP. Optional, up to 255 characters. Comes back in webhooks as `service_internal_code`. |
| `productionInternalCode` | Internal code of the production line. Required. |
| `carpenterEmail`, `carpenterName` | Carpenter's email and name. Required. |
| `carpenterInternalCode` | Carpenter's (customer's) code in your system. Required. |
| `parts` | The service's parts, from 1 to 500. |

Before creating the service, the route registers the carpenter in Cortecloud, if they don't exist yet, and links them to the service center with `carpenterInternalCode`, as in [embedded login](https://apis.cortecloud.com.br/docs/en/guias/login-embutido.md#novo-servico-para-um-vendedor). If the carpenter already has an active link with the service center, that link's internal code is kept. If `carpenterEmail` already belongs to a user with another profile (for example, a salesperson), they become a carpenter and lose the previous profile.

### Parts {#pecas}

`parts` follows the [structure of the JSON file import](https://apis.cortecloud.com.br/docs/en/guias/importacao-json.md#estrutura-do-arquivo): the same fields, measurements in millimeters and the same `machining` object, described in [Machining](https://apis.cortecloud.com.br/docs/en/guias/importacao-json.md#usinagem). The differences are in the materials and in validation:

| Field | In the import | Here |
| --- | --- | --- |
| `material` | Board name in your system. | The part's board: `{ "internalCode": "..." }`, with the board's internal code at the service center. Required. |
| `client`, `furniture` | Do not exist: the carpenter picks the customer during the import. | The carpenter's customer and the part's room (for example, "Kitchen"), up to 255 characters each. Optional: parts with the same pair go to the same customer of the service, and parts without them go to a customer with no name. |
| `c1`, `c2`, `l1`, `l2` | Edge band name. | `{ "internalCode": "..." }` with the edge band's internal code at the service center. Side without edge band: `null` or absent. |
| `quantity`, `c`, `l` | A part with a missing, zero or negative value is discarded. | A missing, zero or negative value responds with `400`. `c` and `l` go up to 9999.99. |

Board and edge band internal codes, `function` and `complement` take up to 255 characters; beyond that, the route responds with `400`.

Since materials arrive by internal code, the import's [material linking](https://apis.cortecloud.com.br/docs/en/guias/importacao-json.md#vinculo-de-materiais) step does not exist.

The same rules as the import apply:

- An empty `function` becomes "Peça".
- Machining is only applied if the production line has a machining machine (see [When the production line does not machine](https://apis.cortecloud.com.br/docs/en/guias/importacao-json.md#quando-a-linha-de-producao-nao-usina)).
- Each part uses at most two different edge bands. If the service center does not accept two edge bands per part, the sides with the second edge band are left without edge band.

There is no field for part rotation: the part may rotate in the cutting plan when the board has no grain.

## Response and follow-up {#resposta-e-acompanhamento}

The `202` response carries the service `id`:

```json
{ "id": 98765 }
```

The `202` confirms the body format and the carpenter registration. Materials, production line and parts are validated later, asynchronously: a nonexistent board code, for example, does not change the response. The result arrives by [webhook](https://apis.cortecloud.com.br/docs/en/guias/webhooks.md#criacao-de-servico):

- `service.created`: the service was created and its parts were saved (status `1`);
- `service.creation_failed`: creation failed, and `errors` lists the reasons.

`service.created` goes out after the service is sent to optimization. When the quote is ready, `service.quoted` arrives. If sending is rejected, for example because a part is larger than the board, `service.creation_failed` arrives with the reasons. To receive all three, request a destination for each type (see [How to enable](https://apis.cortecloud.com.br/docs/en/guias/webhooks.md#como-ativar)).

While Cortecloud fills in the parts, the service is locked for editing in the apps.

### Part ids {#ids-das-pecas}

The quote and the parts are in [`GET /services/{id}`](https://apis.cortecloud.com.br/docs/swagger#/Services/getService). `parts[].id` is each part's id in Cortecloud: use it to match the parts with your system, for example with the machining `DrillCode`.

## What the carpenter sees {#o-que-o-marceneiro-ve}

The service belongs to the service center and is associated with the carpenter. It shows up in the carpenter's Cortecloud starting at the approved status (`6`), as read-only.

## Errors {#erros}

| Status | When |
| --- | --- |
| `400` | Body out of format: missing required field, invalid email, empty `parts` or more than 500 parts, part without `material`, non-positive quantity or measurement, `machining` out of the import format. |
| `401` | Basic authentication. The route requires HMAC. |

Errors in materials, production line or parts, including a part larger than the board, arrive in `service.creation_failed`, not in the response.

:::caution Retry after a timeout
`serviceInternalCode` is not checked for duplicates. If the response is lost and your integration repeats the call, Cortecloud may create the service twice.
:::
