> For the complete documentation index, see [llms.txt](https://docs.perfectcs2.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.perfectcs2.com/documentacao/services.md).

# Serviços

API de serviços 1.1: inventário, custom models, configs e Walkbot.

Esta extensão usa os sistemas reais da Perfect e mantém os controles dos scripts no visual v4. Lua continua embutido na DLL. Scripts ficam em `Documentos\Perfect\Scripts`.

## Chamadas assíncronas

Todos os métodos abaixo recebem `(parametros, callback_opcional)` e retornam um ID de requisição. Também podem ser chamados com `api.request("inventario.metodo", parametros, callback)` — use o nome real em inglês, por exemplo `inventory.list`.

```lua
inventory.list({offset=0, limit=20}, function(result)
    if not result.ok then print(result.error); return end
    for _, item in ipairs(result.items) do
        print(item.id, item.name, item.custom_name)
    end
end)
```

Sem callback, use `api.poll(id)` num callback posterior. Enquanto pendente, retorna `nil, "pending"`. Quando pronto, retorna a tabela e consome o resultado. IDs são exclusivos do script que os solicitou; reload descarta sua fila. Com callback, o resultado é entregue uma vez, no render thread, sem necessidade de poll. `render.*` continua exclusivo de `draw`; atualize variáveis ou controles no callback de serviço.

`api.cancel(id)` descarta a requisição/resultado local; **não desfaz uma ação já enviada ao backend**. Unload descarta requisições ainda não executadas. Falha de validação no envio retorna `nil, erro`; erro na operação retorna `{ok=false,error="..."}` ao callback/poll. Um erro Lua dentro do callback interrompe somente aquele script.

Até 32 requisições/resultados por script, parâmetros até 64 KiB, respostas até 256 KiB. O runtime processa no máximo quatro operações por frame, uma por script, alternando entre scripts. Entre operações, verifica o orçamento de 2 ms; uma chamada nativa individual não pode ser interrompida. Use paginação e atualize listas quando necessário, não a cada tick.

`{ok=true,queued=true}` significa aceitação na fila, **não conclusão**. Observe o snapshot posterior. No caso de edição, há uma confirmação específica em `inventory.edit_result`.

## Descoberta e JSON

* `api.capabilities()` retorna `version`, `build`, `services`, `request_limit`, `async` e `send_packet`. A lista já considera a versão da DLL.
* `menu.list()` / `menu.info(path)` continuam sendo a referência das opções nativas presentes. Incluem agora Walkbot, custom models, Auto Buy, partículas, hit marker, remoções, controles adicionais de movimento, Humanize, verificações do Triggerbot e preferências.
* `json.encode(tabela)` / `json.decode(texto)` retornam valor ou `nil, erro`. Aceitam booleanos, strings, números finitos e tabelas, até oito níveis. Arrays devem ser consecutivos, sem misturar campos. Não aceitam ciclos, funções ou userdata. JSON `null` vira `nil`; portanto não preserva buracos em arrays. Tabela vazia codifica como objeto.

As permissões são verificadas tanto no envio quanto na execução. Uma função pode existir na tabela Lua, mas retornar indisponível na build atual. Não há acesso genérico aos comandos internos do host.

## Inventário

Disponível nas versões com Inventory. Opera somente sobre os itens locais da Perfect; não altera o inventário Steam.

| Método                  | Parâmetros                                        | Resultado relevante                                                |
| ----------------------- | ------------------------------------------------- | ------------------------------------------------------------------ |
| `inventory.status`      | `{}`                                              | `ready`, `catalog_ready`, `error`                                  |
| `inventory.list`        | `offset=0`, `limit=50` (1–100), `search=""`       | `items`, `total`, `offset`; busca literal, diferencia maiúsculas   |
| `inventory.get`         | `id`                                              | `item`                                                             |
| `inventory.equip`       | `id`, `team="t"/"ct"/"both"/"none"`               | `queued`                                                           |
| `inventory.remove`      | `id`                                              | `queued`; remove esse item local                                   |
| `inventory.duplicate`   | `id`, `count=1` (1–20)                            | `queued`; itens comuns, sem unidades de armazenamento              |
| `inventory.edit`        | `id`, `changes={...}`                             | `queued`, `operation`                                              |
| `inventory.edit_result` | `operation`                                       | `pending=true`, ou `saved=true`; resultado final consumido uma vez |
| `inventory.cases`       | `offset=0`, `limit=50`                            | `cases`, `total`, `offset`; catálogo real de caixas                |
| `inventory.add_case`    | `definition`, `count=1` (1–20), `with_keys=false` | `queued`                                                           |

**IDs de itens são strings**, inclusive `casket`, para preservar os 64 bits. Não converta com `tonumber`. Registros incluem definition, paint\_kit, name, custom\_name, seed, wear, stattrak, kills, rarity, quality, equipped (1=T, 2=CT, 3=ambos), slot\_t/slot\_ct, can\_equip, stickers, charm/charm\_seed/charm\_sticker e casket/casket\_items. `kind`: 0 caixa, 1 chave, 2 item.

`changes` aceita: `custom_name` (até 63 bytes UTF-8, sem controles), `wear` (limites reais do acabamento), `seed` (0–1000), `stattrak` (booleano), `kills` (-1–999999999). Outros campos são rejeitados; não é possível trocar identidade, definição, propriedade ou slots por esse patch. Edição usa a mesma verificação de conflito do menu. Há até 16 edições nativas pendentes; consulte `edit_result`, cujo token expira após cinco minutos. Expirar/descartar o token não cancela uma edição já enviada.

```lua
inventory.edit({id=item_id, changes={custom_name="Minha AK"}}, function(r)
    if not r.ok then print(r.error); return end
    local operation = r.operation
    local function check()
        inventory.edit_result({operation=operation}, function(done)
            if done.pending then client.delay(0.2, check)
            elseif done.ok then print("Nome salvo")
            else print(done.error) end
        end)
    end
    check()
end)
```

Ainda não expõe criação arbitrária de skins pelo catálogo completo, alteração de stickers/charms ou abertura de caixas por Lua. As funções de edição existentes no menu permanecem disponíveis pela interface.

## Custom models

Disponível nas versões com Inventory. `models.list({offset=0,limit=50})` retorna `models`, `total`, `scanning`, `error`, `character={id,enabled}` e `melee={id,enabled}`. Cada modelo tem `id`, `name`, `kind` (0 ambos, 1 personagem, 2 corpo a corpo) e `error`.

* `models.select({slot="character" ou "melee",id="..."})`: seleciona somente um modelo listado, compatível e sem erro. ID vazio remove a seleção. Não ativa automaticamente.
* `models.enable({slot="character" ou "melee",enabled=true})`: usa o toggle nativo correspondente.
* `models.refresh({})`: pede nova varredura da pasta já configurada na Perfect. Não permite escolher diretórios arbitrários.

As mudanças continuam participando do sistema de config da Perfect. Não há sistema paralelo de loadouts.

## Configs

Usa as mesmas configs da aba Configs, com a conexão da Perfect:

| Método                          | Parâmetros                                 |
| ------------------------------- | ------------------------------------------ |
| `configs.list`                  | `offset=0`, `limit=50` (1–100)             |
| `configs.load` / `configs.save` | `id` retornado pela lista                  |
| `configs.create`                | `name` (1–80 bytes)                        |
| `configs.rename`                | `id`, `name`                               |
| `configs.import`                | `id` contendo o código de compartilhamento |

A lista retorna `configs`, `total`, `offset`, `loaded_id` e `loading_id`. Alterações são enfileiradas; observe a lista e `loaded_id` para acompanhar o carregamento. Não há exclusão de configs nem envio ao chat nesta API.

## Automação e Grenade Helper

`walkbot.status({})` retorna status/reason, enabled/active/loading, mapa, posição, destino, velocidade, distância, áreas visitadas, recálculos, recuperações, destinos alcançados, rota e eventos. A rota é limitada a 256 pontos (`route_truncated` indica corte), eventos a 32. Não expõe ponteiros do jogo.

`walkbot.action({action=...})` aceita `new_destination`, `replan`, `reload_map`, `reset_visited`. Opções usam `menu.set("walkbot.enabled",true)` etc. Seguem as restrições nativas, inclusive Safe Mode; não ativam automaticamente outras funções.

`grenades.list({map="de_mirage",source="all",offset=0,limit=50})` consulta spots do usuário e padrões. `source`: `all`, `user`, `default`; mapa vazio lista todos. Retorna `spots`, `total`, `offset`, `revision` (string). Cada spot inclui sua origem em `source`, nome, mapa, tipo, lançamento, botão, posição e ângulo. É uma consulta, sem substituir a biblioteca de spots.

## Validação

Testes locais cobrem filas, callbacks, polling, cancelamento, descarregamento, isolamento de erros, JSON, limites, permissões de build e integração com o registro nativo. Compilação não substitui validação no CS2: aplicação de itens/modelos e serviços online precisam de uma sessão real. Esta é uma expansão funcional, não uma promessa de cobertura de 100% do jogo.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.perfectcs2.com/documentacao/services.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
