# Lê um item: saldo, posições, bloqueios, política e atributos

**GET** `/v1/objects/product/{id}`

`current_assignments` são as posições do item, com o saldo e a reposição de cada uma; `blocks` diz o que está parado e por quê. `depot` recorta a um CD.

> **Ação da chave: `product.get`** Quem cria a chave escolhe as ações que ela abre; sem esta, a rota recusa com `api_key_action_not_granted`.

## Parâmetros do caminho

- `id` (string, obrigatório)

## Parâmetros da consulta

- `depot` (string): O código do CD que recorta a ficha.
- `source` (string): A origem da leitura, para o livro de recusas.

## Devolve

O `data` do envelope `{ ok, data, error, error_code, field, trace_id }`:

- `product` (objeto, obrigatório)
  - `active` (boolean)
  - `blocks` (lista de objeto)
    - `location_code` (string)
    - `location_status` (string)
    - `lot_code` (string, ou nulo)
    - `qty` (integer)
    - `reason` (string): `held`, `missing`, `unverified`, `damaged`, `quarantine`, `expired` ou `stopped`.
  - `codes` (lista de any): Os outros códigos do item.
  - `complete` (boolean): O cadastro tem o que o galpão precisa para operar o item.
  - `components` (lista de any): Os itens do kit; vazio no item comum.
  - `created_at` (data e hora)
  - `current_assignments` (lista de objeto)
    - `in_reach` (boolean): A posição está nos CDs de quem pede.
    - `kind` (string): O papel da posição para o item (`picking`, `bulk`…).
    - `location` (objeto)
    - `qty_on_hand` (integer)
    - `replenish` (objeto, ou nulo)
  - `description` (string)
  - `ean` (string, ou nulo)
  - `id` (uuid)
  - `in_kits` (lista de any): Os kits de que o item faz parte.
  - `last_receipt` (objeto, ou nulo): A última nota com o item, no recorte de depósito e alcance de quem lê. Nula sem nota.
    - `created_at` (data e hora)
    - `id` (uuid)
    - `nfe_key` (string, ou nulo)
    - `short_code` (string, ou nulo)
    - `status` (string)
    - `supplier_name` (string, ou nulo)
  - `next_order` (objeto, ou nulo): A próxima OS aberta com parada do item (fora a conferência). Nula sem nenhuma.
    - `from_location_code` (string, ou nulo)
    - `id` (uuid)
    - `kind` (string)
    - `location_code` (string)
    - `short_code` (string, ou nulo)
    - `status` (string)
  - `policy_max_places` (integer, ou nulo)
  - `policy_name` (string, ou nulo)
  - `policy_replenish_max` (integer, ou nulo)
  - `policy_replenish_min` (integer, ou nulo)
  - `policy_requires_kind` (string, ou nulo)
  - `qty_available` (integer): O que pode ser vendido agora.
  - `qty_blocked` (integer)
  - `qty_expired` (integer): Em lote vencido.
  - `qty_held` (integer): Reservado por pedido.
  - `qty_on_hand` (integer): Tudo o que está no galpão.
  - `qty_on_hold` (integer)
  - `qty_stopped` (integer): Em posição parada.
  - `replenish_max` (integer, ou nulo)
  - `replenish_min` (integer, ou nulo)
  - `short_code` (string, ou nulo)
  - `sku` (string, ou nulo)
  - `tracks_lot` (boolean)
  - `trait_specs` (lista de objeto): Os atributos que o tipo do item pede, com as unidades.
    - `entry` (lista de objeto)
    - `key` (string)
    - `natures` (lista de string)
    - `unit` (string)
  - `traits` (objeto): Os atributos do item, pelo catálogo da empresa, na unidade base (peso em g, medidas em mm).
  - `units` (lista de any): As embalagens do item (caixa, fardo), com o fator.
  - `uom` (string): A unidade de medida, pelo código da NF-e (`H87` é peça).
  - `weight_on_hand_g` (integer, ou nulo)

## Recusas

### HTTP 400 · Pedido mal formado

- [`version_unknown`](/erros/version_unknown.md) (HTTP 400): A `Kernos-Version` pedida não existe. Use uma das versões declaradas no cabeçalho, ou não o mande.

### HTTP 401 · Sem credencial válida

- [`api_key_expired`](/erros/api_key_expired.md) (HTTP 401): A chave venceu. Gire a chave no painel e use a nova.
- [`api_key_wrong_environment`](/erros/api_key_wrong_environment.md) (HTTP 401): A chave é do outro ambiente: `ksk_test_` vai em https://stag.kernos.com.br, `ksk_live_` em https://api.kernos.com.br.
- [`unauthenticated`](/erros/unauthenticated.md) (HTTP 401): Credencial ausente, inválida ou expirada.

### HTTP 403 · Sem permissão

- [`agent_token_out_of_scope`](/erros/agent_token_out_of_scope.md) (HTTP 403): O token de agente (`kat_`) só vale na porta MCP. Para a API, use o token de sessão ou uma chave de integração.
- [`api_key_action_not_granted`](/erros/api_key_action_not_granted.md) (HTTP 403): A chave não tem esta ação. Edite as ações da chave no painel.
- [`api_key_out_of_scope`](/erros/api_key_out_of_scope.md) (HTTP 403): A chave só vale nas rotas do contrato público.
- [`depot_out_of_reach`](/erros/depot_out_of_reach.md) (HTTP 403): Quem chama não alcança o CD deste objeto. Peça alcance ao CD ou use outra credencial.
- [`forbidden_role`](/erros/forbidden_role.md) (HTTP 403): O papel de quem chama nesta empresa não permite esta ação.
- [`module_not_subscribed`](/erros/module_not_subscribed.md) (HTTP 403): A empresa não assina o módulo desta rota.
- [`tenant_mismatch`](/erros/tenant_mismatch.md) (HTTP 403): A credencial não pertence à empresa do endereço chamado.
- [`tenant_unavailable`](/erros/tenant_unavailable.md) (HTTP 403): A empresa está indisponível no momento.

### HTTP 404 · Não encontrado

- [`not_found`](/erros/not_found.md) (HTTP 404): Não existe objeto com esse identificador nesta empresa.

### HTTP 429 · Muitos pedidos

- [`rate_limited`](/erros/rate_limited.md) (HTTP 429): Muitos pedidos por segundo com esta chave. Espere o `Retry-After`, em segundos, e tente de novo.

#### curl

**Lê um item: saldo, posições, bloqueios, política e atributos**

```sh
curl -X GET "https://stag.kernos.com.br/v1/objects/product/<id>" \
  -H "Authorization: Bearer ksk_test_…" \
  -H "Kernos-Version: 2026-10-03"
```

#### Node

**Lê um item: saldo, posições, bloqueios, política e atributos**

```js
import { Kernos } from '@kernosbr/kernos'

const kernos = new Kernos(process.env.KERNOS_API_KEY)
const result = await kernos.product.get('<id>')
```

#### Python

**Lê um item: saldo, posições, bloqueios, política e atributos**

```python
import os
from kernos import Kernos

kernos = Kernos(os.environ["KERNOS_API_KEY"])
result = kernos.product.get("<id>")
```

#### PHP

**Lê um item: saldo, posições, bloqueios, política e atributos**

```php
<?php
$kernos = new Kernos\Kernos(getenv('KERNOS_API_KEY'));
$result = $kernos->product->get('<id>');
```

#### Java

**Lê um item: saldo, posições, bloqueios, política e atributos**

```java
Kernos kernos = new Kernos(System.getenv("KERNOS_API_KEY"));
JsonNode result = kernos.product().get("<id>");
```

#### C#

**Lê um item: saldo, posições, bloqueios, política e atributos**

```csharp
var kernos = new KernosClient(Environment.GetEnvironmentVariable("KERNOS_API_KEY"));
var result = await kernos.Product.GetAsync("<id>");
```

#### Go

**Lê um item: saldo, posições, bloqueios, política e atributos**

```go
client, err := kernos.New(os.Getenv("KERNOS_API_KEY"))
result, err := client.Product.Get(ctx, "<id>", nil)
```

#### Rust

**Lê um item: saldo, posições, bloqueios, política e atributos**

```rust
let kernos = Kernos::new(&std::env::var("KERNOS_API_KEY")?)?;
let result = kernos.product().get("<id>", None, None)?;
```

**Resposta · 200 (a forma, sem dado real)**

```json
{
  "ok": true,
  "data": {
    "product": {
      "active": true,
      "blocks": [
        {
          "location_code": "…",
          "location_status": "…",
          "lot_code": "…",
          "qty": 0,
          "reason": "…"
        }
      ],
      "codes": [
        null
      ],
      "complete": true,
      "components": [
        null
      ],
      "created_at": "2026-10-03T12:00:00Z",
      "current_assignments": [
        {
          "in_reach": true,
          "kind": "…",
          "location": {},
          "qty_on_hand": 0,
          "replenish": {}
        }
      ],
      "description": "…",
      "ean": "…",
      "id": "3f1e0c8a-5b7d-4c21-9a3e-0b1c2d3e4f50",
      "in_kits": [
        null
      ],
      "last_receipt": {
        "created_at": "2026-10-03T12:00:00Z",
        "id": "3f1e0c8a-5b7d-4c21-9a3e-0b1c2d3e4f50",
        "nfe_key": "…",
        "short_code": "…",
        "status": "…",
        "supplier_name": "…"
      },
      "next_order": {
        "from_location_code": "…",
        "id": "3f1e0c8a-5b7d-4c21-9a3e-0b1c2d3e4f50",
        "kind": "…",
        "location_code": "…",
        "short_code": "…",
        "status": "…"
      },
      "policy_max_places": 0,
      "policy_name": "…",
      "policy_replenish_max": 0,
      "policy_replenish_min": 0,
      "policy_requires_kind": "…",
      "qty_available": 0,
      "qty_blocked": 0,
      "qty_expired": 0,
      "qty_held": 0,
      "qty_on_hand": 0,
      "qty_on_hold": 0,
      "qty_stopped": 0,
      "replenish_max": 0,
      "replenish_min": 0,
      "short_code": "…",
      "sku": "…",
      "tracks_lot": true,
      "trait_specs": [
        {
          "entry": [],
          "key": "…",
          "natures": [],
          "unit": "…"
        }
      ],
      "traits": {},
      "units": [
        null
      ],
      "uom": "…",
      "weight_on_hand_g": 0
    }
  },
  "error": null,
  "error_code": null,
  "field": null,
  "trace_id": null
}
```

> **Ambiente** `ksk_test_` fala com `https://stag.kernos.com.br`; `ksk_live_`, com `https://api.kernos.com.br`. O prefixo da chave escolhe o endereço.
