Criar e editar modelos
Cria, altera, duplica e apaga modelos de documento, com as regras do modelo padrão e a proteção das imagens.
Cada tipo de documento e idioma tem exatamente um modelo padrão, que a plataforma usa ao gerar faturas e romaneios sem que ninguém escolha. Você pode criar quantos modelos quiser, mas o padrão é protegido: não pode ser apagado, e não pode deixar de ser padrão sem que outro assuma. O HTML passa por uma verificação que bloqueia imagens apontando para endereços internos.
Criar
/api/v1/admin/documentsAdminCriar um modelo
Corpo da requisição
namestringobrigatórioNome do modelo, até 255 caracteres.
typestringobrigatórioinvoicepacking_slipcredit_memocustomTipo.
body_htmlstringobrigatórioHTML do documento com marcadores
{{variavel}}. Em <img src> valem URLs http(s) públicas, caminhos relativos e {{variaveis}}; imagens data: base64 são hospedadas automaticamente.variablesarraypadrão: []Nomes das variáveis usadas (informativo).
is_defaultbooleanpadrão: falsetrue torna este o padrão do tipo e idioma e desmarca o anterior.languagestringpadrão: pt-BRIdioma.
Exemplo de requisição (criar)
bash
curl -X POST "$BASE_URL/api/v1/admin/documents" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Etiqueta de pedido", "type": "custom", "body_html": "<h1>Pedido {{order_number}}</h1><p>{{customer_name}} total {{total}}</p>", "variables": ["order_number", "customer_name", "total"], "language": "pt-BR"}'Resposta (criar)
201Modelo criado
json
{
"id": "3204f98e-2c66-42d5-baee-bbc191a1b063",
"name": "Etiqueta de pedido",
"type": "custom",
"body_html": "<h1>Pedido {{order_number}}</h1><p>{{customer_name}} total {{total}}</p>",
"variables": ["order_number", "customer_name", "total"],
"is_default": false,
"language": "pt-BR",
"created_at": "2026-10-11T21:19:07.694671Z",
"updated_at": "2026-10-11T21:19:07.694671Z"
}Campos da resposta
iduuidId do modelo.
namestringNome do modelo.
typestringinvoicepacking_slipcredit_memocustomTipo do documento.
body_htmlstringO HTML do documento, com marcadores
{{variavel}}. As aspas, < e > vêm escapados como \u003c no JSON (é só a forma de escrever; ao decodificar volta o HTML).variablesarrayNomes das variáveis que o autor declarou usar. É informativo: é gravado como veio, não é calculado nem conferido contra o corpo.
is_defaultbooleanSe é o modelo padrão do seu tipo e idioma.
languagestringIdioma, por exemplo
pt-BR.created_atstringCriação, RFC 3339.
updated_atstringÚltima alteração, RFC 3339.
Erros (criar)
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 400 | Corpo que não é JSON válido. | {"error":"invalid JSON body","detail":"..."} |
| 400 | Falta name, type ou body_html. | {"error":"name, type, and body_html are required"} |
| 400 | <img src> aponta para endereço interno, ou tem esquema data:/javascript: que não pôde ser hospedado. | {"error":"invalid_image_src","detail":"invalid_image_src: ssrf_forbidden: url targets internal/private/loopback address (src=http://127.0.0.1/x.png)"} |
| 500 | type fora de invoice, packing_slip, credit_memo, custom. Hoje volta como 500, não 400. | {"error":"failed to create document","detail":"invalid document type: foo"} |
Alterar
/api/v1/admin/documents/{id}AdminAlterar um modelo
Parâmetros de caminho
iduuidobrigatórioId do modelo (UUID).
Corpo da requisição
namestringNome do modelo, até 255 caracteres.
typestringinvoicepacking_slipcredit_memocustomTipo.
body_htmlstringHTML do documento com marcadores
{{variavel}}. Em <img src> valem URLs http(s) públicas, caminhos relativos e {{variaveis}}; imagens data: base64 são hospedadas automaticamente.variablesarrayNomes das variáveis usadas (informativo).
is_defaultbooleantrue torna este o padrão do tipo e idioma e desmarca o anterior.languagestringIdioma.
Exemplo de requisição (alterar)
bash
curl -X PUT "$BASE_URL/api/v1/admin/documents/3204f98e-2c66-42d5-baee-bbc191a1b063" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Etiqueta de pedido v2"}'Resposta (alterar)
200Modelo alterado
json
{
"id": "3204f98e-2c66-42d5-baee-bbc191a1b063",
"name": "Etiqueta de pedido v2",
"type": "custom",
"body_html": "<h1>Pedido {{order_number}}</h1><p>{{customer_name}} total {{total}}</p>",
"variables": ["order_number", "customer_name", "total"],
"is_default": false,
"language": "pt-BR",
"created_at": "2026-10-11T21:19:07.694671Z",
"updated_at": "2026-10-11T21:19:07.694671Z"
}Campos da resposta
(objeto)objectO modelo depois da alteração. Só os campos enviados mudam (alteração parcial).
Erros (alterar)
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 400 | Corpo que não é JSON válido. | {"error":"invalid JSON body","detail":"..."} |
| 404 | O modelo não existe. | {"error":"document not found"} |
| 400 | <img src> aponta para endereço interno, ou tem esquema data:/javascript: que não pôde ser hospedado. | {"error":"invalid_image_src","detail":"invalid_image_src: ssrf_forbidden: url targets internal/private/loopback address (src=http://127.0.0.1/x.png)"} |
| 409 | Tirar is_default do único modelo padrão do tipo e idioma. | {"error":"documents.last_default_protected","detail":"documents: cannot unset is_default \u2014 at least one default template must exist for this type+language; mark another template as default first"} |
| 500 | type fora de invoice, packing_slip, credit_memo, custom. Hoje volta como 500, não 400. | {"error":"failed to update document","detail":"invalid document type: foo"} |
Duplicar
/api/v1/admin/documents/{id}/duplicateAdminDuplicar um modelo
Parâmetros de caminho
iduuidobrigatórioId do modelo (UUID).
Exemplo de requisição (duplicar)
bash
curl -X POST "$BASE_URL/api/v1/admin/documents/3204f98e-2c66-42d5-baee-bbc191a1b063/duplicate" \
-H "Authorization: Bearer $TOKEN"Resposta (duplicar)
201Cópia criada
json
{
"id": "3204f98e-2c66-42d5-baee-bbc191a1b063",
"name": "Etiqueta de pedido (copy)",
"type": "custom",
"body_html": "<h1>Pedido {{order_number}}</h1><p>{{customer_name}} total {{total}}</p>",
"variables": ["order_number", "customer_name", "total"],
"is_default": false,
"language": "pt-BR",
"created_at": "2026-10-11T21:19:07.694671Z",
"updated_at": "2026-10-11T21:19:07.694671Z"
}Campos da resposta
(objeto)objectO novo modelo: o nome ganha o sufixo
(copy) (em inglês) e a cópia nunca é padrão.Erros (duplicar)
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 404 | O modelo não existe. | {"error":"document not found"} |
| 500 | Falha inesperada no servidor. | {"error":"failed to ..."} |
Apagar
/api/v1/admin/documents/{id}AdminApagar um modelo
Parâmetros de caminho
iduuidobrigatórioId do modelo (UUID).
Exemplo de requisição (apagar)
bash
curl -X DELETE "$BASE_URL/api/v1/admin/documents/3204f98e-2c66-42d5-baee-bbc191a1b063" \
-H "Authorization: Bearer $TOKEN"Resposta (apagar)
200Modelo apagado
json
{
"message": "document deleted"
}Campos da resposta
messagestringTexto fixo de confirmação, em inglês.
Erros (apagar)
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 404 | O modelo não existe. | {"error":"document not found"} |
| 403 | O modelo é o padrão do seu tipo. | {"error":"cannot delete default document template"} |
| 500 | Falha inesperada no servidor. | {"error":"failed to ..."} |