/int-bling
Bling ERP integration via API v3. Manage products, sales orders, contacts, fiscal invoices (NF-e), and stock. Use when users ask about ERP data, products, orders, contacts, invoices, or inventory from Bling. Integração com ERP Bling: produtos, pedidos, contatos, NF-e, estoque.
$ npx -y skills add evolution-foundation/evo-nexus --skill int-bling --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/int-bling
Context preview
The summary Claude sees to decide when to auto-load this skill.
Bling ERP integration via API v3. Manage products, sales orders, contacts, fiscal invoices (NF-e), and stock. Use when users ask about ERP data, products, orders, contacts, invoices, or inventory from Bling. Integração com ERP Bling: produtos, pedidos, contatos, NF-e, estoque.
SKILL.md
int-bling.SKILL.mdname: int-bling
description: "Bling ERP integration via API v3. Manage products, sales orders, contacts, fiscal invoices (NF-e), and stock. Use when users ask about ERP data, products, orders, contacts, invoices, or inventory from Bling. Integração com ERP Bling: produtos, pedidos, contatos, NF-e, estoque."
Bling ERP Skill
Integration with Bling ERP via REST API v3 (OAuth2 Bearer).
When to use
- List or create products, services, or kits in Bling
- Create or query sales orders
- Manage contacts (customers/suppliers)
- Issue or list fiscal invoices (NF-e)
- Check or update stock levels
Setup
This skill uses a Python client (`scripts/bling_client.py`) that handles OAuth2 Bearer auth with **automatic refresh on 401**. You do OAuth **once** via the CLI, then the skill refreshes tokens transparently forever.
One-time OAuth setup
1. Create an app at https://developer.bling.com.br → "Meus Apps" 2. Set the app's redirect URI to: `http://localhost:8787/callback` 3. Copy the Client ID and Client Secret into `.env`:
BLING_CLIENT_ID=...
BLING_CLIENT_SECRET=...
4. Run the login helper:
make bling-auth
This opens your browser, captures the authorization code via a local callback server, exchanges it for `access_token` + `refresh_token`, and persists both to `.env`.
After this step, `.env` contains:
BLING_CLIENT_ID=...
BLING_CLIENT_SECRET=...
BLING_ACCESS_TOKEN=...
BLING_REFRESH_TOKEN=...
How the auto-refresh works
`scripts/bling_client.py` is the single entry point for all API calls. On any `HTTP 401`, it: 1. Exchanges `BLING_REFRESH_TOKEN` for a new `access_token` + `refresh_token` at `https://www.bling.com.br/Api/v3/oauth/token` (Basic auth with Client ID/Secret) 2. Persists both back to `.env` and `os.environ` 3. Retries the original request once
Bling rotates the refresh token on every refresh, so **always** use this client — never call the API with raw `curl` unless you're debugging, otherwise you risk the `.env` tokens going stale.
Calling the client
python3 .claude/skills/int-bling/scripts/bling_client.py GET /produtos --params page=1 limit=50
python3 .claude/skills/int-bling/scripts/bling_client.py POST /contatos --body '{"nome":"Acme","tipo":"J","numeroDocumento":"12345678000100"}'
python3 .claude/skills/int-bling/scripts/bling_client.py PUT /produtos/123 --body '{"preco":99.90}'The client prints the JSON response to stdout and logs errors to stderr.
---
Base URL
https://www.bling.com.br/Api/v3
---
Products
List products
curl -s -X GET \
"https://www.bling.com.br/Api/v3/produtos?pagina=1&limite=100" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}"**Query params:** | Param | Type | Description | |-------|------|-------------| | `pagina` | number | Page number (default 1) | | `limite` | number | Items per page (default 100, max 100) | | `nome` | string | Filter by product name | | `codigo` | string | Filter by SKU/code | | `tipo` | string | `P`=Product, `S`=Service, `K`=Kit |
Create product
curl -s -X POST \
"https://www.bling.com.br/Api/v3/produtos" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"nome": "Widget Pro",
"codigo": "WGT-001",
"preco": 99.90,
"precoCusto": 45.00,
"tipo": "P",
"formato": "S",
"situacao": "A",
"unidade": "UN"
}'**Body fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | `nome` | string | yes | Product name | | `preco` | number | yes | Sale price | | `tipo` | string | yes | `P`=Product, `S`=Service, `K`=Kit | | `formato` | string | yes | `S`=Simple, `E`=With variations, `V`=Variation | | `codigo` | string | no | SKU/code | | `precoCusto` | number | no | Cost price | | `situacao` | string | no | `A`=Active, `I`=Inactive | | `unidade` | string | no | Unit (UN, KG, etc.) | | `pesoLiquido` | number | no | Net weight in kg | | `pesoBruto` | number | no | Gross weight in kg |
---
Sales Orders
List orders
curl -s -X GET \
"https://www.bling.com.br/Api/v3/pedidos/vendas?pagina=1&limite=100&dataInicial=2026-01-01&dataFinal=2026-04-10" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}"**Query params:** | Param | Type | Description | |-------|------|-------------| | `pagina` | number | Page number | | `limite` | number | Items per page | | `idsSituacoes[]` | number | Filter by status ID | | `dataInicial` | string | Start date `YYYY-MM-DD` | | `dataFinal` | string | End date `YYYY-MM-DD` |
Create order
curl -s -X POST \
"https://www.bling.com.br/Api/v3/pedidos/vendas" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"contato": { "id": 123456 },
"data": "2026-04-10",
"observacoes": "Test order",
"itens": [
{
"produto": { "id": 789 },
"quantidade": 2,
"valor": 99.90,
"desconto": 0
}
]
}'**Body fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | `contato.id` | number | yes | Contact (customer) ID | | `itens` | array | yes | Order line items | | `itens[].produto.id` | number | yes | Product ID | | `itens[].quantidade` | number | yes | Quantity | | `itens[].valor` | number | yes | Unit price | | `itens[].desconto` | number | no | Discount amount | | `data` | string | no | Order date `YYYY-MM-DD` | | `observacoes` | string | no | Notes |
---
Contacts
List contacts
curl -s -X GET \
"https://www.bling.com.br/Api/v3/contatos?pagina=1&limite=100&tipoPessoa=J" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}"**Query params:** | Param | Type | Description | |-------|------|-------------| | `pagina` | number | Page number | | `limite` | number | Items per page | | `nome` | string | Filter by name | | `tipoPessoa` | string | `F`=Individual (CPF
Read more
name: int-bling description: "Bling ERP integration via API v3. Manage products, sales orders, contacts, fiscal invoices (NF-e), and stock. Use when users ask about ERP data, products, orders, contacts, invoices, or inventory from Bling. Integração com ERP Bling: produtos, pedidos, contatos, NF-e, estoque."
Bling ERP Skill
Integration with Bling ERP via REST API v3 (OAuth2 Bearer).
When to use
- List or create products, services, or kits in Bling
- Create or query sales orders
- Manage contacts (customers/suppliers)
- Issue or list fiscal invoices (NF-e)
- Check or update stock levels
Setup
This skill uses a Python client (`scripts/bling_client.py`) that handles OAuth2 Bearer auth with **automatic refresh on 401**. You do OAuth **once** via the CLI, then the skill refreshes tokens transparently forever.
One-time OAuth setup
1. Create an app at https://developer.bling.com.br → "Meus Apps" 2. Set the app's redirect URI to: `http://localhost:8787/callback` 3. Copy the Client ID and Client Secret into `.env`:
BLING_CLIENT_ID=... BLING_CLIENT_SECRET=...
4. Run the login helper:
make bling-auth
This opens your browser, captures the authorization code via a local callback server, exchanges it for `access_token` + `refresh_token`, and persists both to `.env`.
After this step, `.env` contains:
BLING_CLIENT_ID=... BLING_CLIENT_SECRET=... BLING_ACCESS_TOKEN=... BLING_REFRESH_TOKEN=...
How the auto-refresh works
`scripts/bling_client.py` is the single entry point for all API calls. On any `HTTP 401`, it: 1. Exchanges `BLING_REFRESH_TOKEN` for a new `access_token` + `refresh_token` at `https://www.bling.com.br/Api/v3/oauth/token` (Basic auth with Client ID/Secret) 2. Persists both back to `.env` and `os.environ` 3. Retries the original request once
Bling rotates the refresh token on every refresh, so **always** use this client — never call the API with raw `curl` unless you're debugging, otherwise you risk the `.env` tokens going stale.
Calling the client
python3 .claude/skills/int-bling/scripts/bling_client.py GET /produtos --params page=1 limit=50
python3 .claude/skills/int-bling/scripts/bling_client.py POST /contatos --body '{"nome":"Acme","tipo":"J","numeroDocumento":"12345678000100"}'
python3 .claude/skills/int-bling/scripts/bling_client.py PUT /produtos/123 --body '{"preco":99.90}'The client prints the JSON response to stdout and logs errors to stderr.
---
Base URL
https://www.bling.com.br/Api/v3
---
Products
List products
curl -s -X GET \
"https://www.bling.com.br/Api/v3/produtos?pagina=1&limite=100" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}"**Query params:** | Param | Type | Description | |-------|------|-------------| | `pagina` | number | Page number (default 1) | | `limite` | number | Items per page (default 100, max 100) | | `nome` | string | Filter by product name | | `codigo` | string | Filter by SKU/code | | `tipo` | string | `P`=Product, `S`=Service, `K`=Kit |
Create product
curl -s -X POST \
"https://www.bling.com.br/Api/v3/produtos" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"nome": "Widget Pro",
"codigo": "WGT-001",
"preco": 99.90,
"precoCusto": 45.00,
"tipo": "P",
"formato": "S",
"situacao": "A",
"unidade": "UN"
}'**Body fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | `nome` | string | yes | Product name | | `preco` | number | yes | Sale price | | `tipo` | string | yes | `P`=Product, `S`=Service, `K`=Kit | | `formato` | string | yes | `S`=Simple, `E`=With variations, `V`=Variation | | `codigo` | string | no | SKU/code | | `precoCusto` | number | no | Cost price | | `situacao` | string | no | `A`=Active, `I`=Inactive | | `unidade` | string | no | Unit (UN, KG, etc.) | | `pesoLiquido` | number | no | Net weight in kg | | `pesoBruto` | number | no | Gross weight in kg |
---
Sales Orders
List orders
curl -s -X GET \
"https://www.bling.com.br/Api/v3/pedidos/vendas?pagina=1&limite=100&dataInicial=2026-01-01&dataFinal=2026-04-10" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}"**Query params:** | Param | Type | Description | |-------|------|-------------| | `pagina` | number | Page number | | `limite` | number | Items per page | | `idsSituacoes[]` | number | Filter by status ID | | `dataInicial` | string | Start date `YYYY-MM-DD` | | `dataFinal` | string | End date `YYYY-MM-DD` |
Create order
curl -s -X POST \
"https://www.bling.com.br/Api/v3/pedidos/vendas" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"contato": { "id": 123456 },
"data": "2026-04-10",
"observacoes": "Test order",
"itens": [
{
"produto": { "id": 789 },
"quantidade": 2,
"valor": 99.90,
"desconto": 0
}
]
}'**Body fields:** | Field | Type | Required | Description | |-------|------|----------|-------------| | `contato.id` | number | yes | Contact (customer) ID | | `itens` | array | yes | Order line items | | `itens[].produto.id` | number | yes | Product ID | | `itens[].quantidade` | number | yes | Quantity | | `itens[].valor` | number | yes | Unit price | | `itens[].desconto` | number | no | Discount amount | | `data` | string | no | Order date `YYYY-MM-DD` | | `observacoes` | string | no | Notes |
---
Contacts
List contacts
curl -s -X GET \
"https://www.bling.com.br/Api/v3/contatos?pagina=1&limite=100&tipoPessoa=J" \
-H "Authorization: Bearer ${BLING_ACCESS_TOKEN}"**Query params:** | Param | Type | Description | |-------|------|-------------| | `pagina` | number | Page number | | `limite` | number | Items per page | | `nome` | string | Filter by name | | `tipoPessoa` | string | `F`=Individual (CPF
Other skills on evo-nexus.
- /ai-image-creator
Generate PNG images using AI (multiple models via OpenRouter including Gemini, FLUX.2, Riverflow, SeedDream, GPT-5 Image, proxied through Cloudflare AI Gateway BYOK). Also analyze/describe existing images using multimodal AI vision. Use when user asks to "generate an image",
Open skill - /create-agent
Create a new custom agent for the workspace. Guides the user through defining agent name, domain, personality, skills, model, and memory folder. Use when the user says 'create an agent', 'new agent', 'add an agent', 'I need a custom agent', or wants to create a specialized agent
Open skill - /create-command
Create a new slash command for Claude Code. Guides the user through defining the command name, what it does, and generates the markdown file in .claude/commands/. Use when the user says 'create a command', 'new command', 'add a slash command', 'I want a shortcut for', or wants
Open skill - /create-goal
Create a Mission, Project, or Goal (Mission → Project → Goal → Task hierarchy) in EvoNexus. Guides the user through picking a mission, choosing or creating a project, defining a measurable goal with metric_type and target_value. Writes to the SQLite goals tables via POST
Open skill - /create-heartbeat
Create a new heartbeat (proactive agent scheduled with a decision prompt) for EvoNexus. Guides the user through picking an agent, setting interval, wake triggers, and the decision prompt that governs when the agent acts. Writes to config/heartbeats.yaml with pydantic validation.
Open skill - /create-integration
Create a new custom integration (API/service wrapper) for the workspace. Guides the user through defining the integration's slug, display name, description, category, and required env keys. Writes .claude/skills/custom-int-{slug}/SKILL.md via POST /api/integrations/custom. Use
Open skill

