1. Before the examples
All examples use the token kept in the LUA_TOKEN environment variable and the address https://painel.lua.email/api/v1. To create the token and learn about permissions, limits and errors, read the integration guide.
In the Python examples, the call function below sends the call and, if the panel asks for a pause (429), waits the time indicated and tries again. The other Python examples use this function.
import os
import time
import requests
BASE = "https://painel.lua.email/api/v1"
HEADERS = {"Authorization": "Bearer " + os.environ["LUA_TOKEN"]}
def call(method, path, **options):
while True:
response = requests.request(method, BASE + path, headers=HEADERS, timeout=30, **options)
if response.status_code != 429:
return response
time.sleep(int(response.headers.get("Retry-After", "5")))
In the addresses, what is between braces, such as {domain} or {mailbox}, must be replaced with the domain or the full mailbox address. The examples use the fictional domain yourcompany.com.
In the tables, the Permission column shows the permission for the area. Every query (GET) is also accepted with the Read permission; creating, changing and removing require the permission for the area.
2. Domains
Looks up your company's or your team's domains, with the Read permission. Requesting a new domain requires the Support permission and the Request a domain through the API option enabled in the user record.
| Method | Address | Permission | What it does |
|---|---|---|---|
GET | /api/v1/domains | Reading | Lists your domains. |
GET | /api/v1/domains/{domain} | Reading | Looks up a domain. |
POST | /api/v1/domains | Support | Requests a new domain, which stays pending until the TXT record is checked in DNS. |
GET | /api/v1/domain-requests/{request_id} | Reading | Looks up a domain request. |
curl -H "Authorization: Bearer $LUA_TOKEN" "https://painel.lua.email/api/v1/domains?per_page=100"
page = 1
while True:
body = call("GET", "/domains", params={"page": page, "per_page": 100}).json()
for domain in body["data"]:
print(domain["domain"], domain["mailboxes"], "caixas")
if page >= body["pagination"]["total_pages"]:
break
page += 1
3. Mailboxes
Operations to list, create, activate, deactivate and remove mailboxes, change the password and check storage use.
| Method | Address | Permission | What it does |
|---|---|---|---|
GET | /api/v1/domains/{domain}/mailboxes | Mailboxes | Lists the mailboxes of a domain. |
POST | /api/v1/domains/{domain}/mailboxes | Mailboxes | Creates a mailbox. |
GET | /api/v1/mailboxes/{mailbox} | Mailboxes | Looks up a mailbox. |
PUT | /api/v1/mailboxes/{mailbox} | Mailboxes | Changes a mailbox. |
DELETE | /api/v1/mailboxes/{mailbox} | Mailboxes | Removes a mailbox, following the panel removal rules. |
PUT | /api/v1/mailboxes/{mailbox}/active | Mailboxes | Activates or deactivates a mailbox. |
POST | /api/v1/mailboxes/{mailbox}/license | Mailboxes | Assigns a license to a mailbox that has none. |
POST | /api/v1/mailboxes/{mailbox}/password | Mailboxes | Changes the mailbox password and returns a secure link with the new password. |
PUT | /api/v1/mailboxes/{mailbox}/2fa | Mailboxes | Turns two-step verification (2FA) on or off for the mailbox. |
GET | /api/v1/mailboxes/{mailbox}/quota | Reading | Shows the mailbox storage use and the current plan. |
GET | /api/v1/mailboxes/{mailbox}/removal | Mailboxes | Shows the status of the mailbox removal request. |
POST | /api/v1/mailboxes/{mailbox}/removal | Mailboxes | Puts the mailbox in the removal queue, like the Remove button on screen. The request can be canceled in the panel while it is pending. |
List the mailboxes of a domain
Only active mailboxes by default. Use active_only=false to include inactive ones and search to look for part of the address or name.
curl -H "Authorization: Bearer $LUA_TOKEN" \
"https://painel.lua.email/api/v1/domains/yourcompany.com/mailboxes?per_page=100"
body = call("GET", "/domains/yourcompany.com/mailboxes", params={"per_page": 100}).json()
for mailbox in body["data"]:
print(mailbox["username"], mailbox["name"], mailbox["active"])
{
"success": true,
"data": [
{
"id": 101,
"username": "maria@yourcompany.com",
"name": "Maria Souza",
"domain": "yourcompany.com",
"active": true,
"quota": 10737418240,
"x_client_license_id": 7,
"created": "2026-03-01T08:00:00",
"modified": "2026-09-02T16:30:00"
}
],
"pagination": {"page": 1, "per_page": 100, "total": 1, "total_pages": 1}
}
Create a mailbox
Requires the Mailboxes permission. The password must meet the panel password policy. The license (x_client_license_id) defines the mailbox plan and storage; it must belong to your company and have a free seat. The license number appears in the x_client_license_id field of existing mailboxes. A mailbox without a license cannot be activated.
curl -X POST \
-H "Authorization: Bearer $LUA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"username": "ana@yourcompany.com", "password": "Troque-Esta-Senha-9", "name": "Ana Lima", "x_client_license_id": 7}' \
"https://painel.lua.email/api/v1/domains/yourcompany.com/mailboxes"
response = call("POST", "/domains/yourcompany.com/mailboxes", json={
"username": "ana@yourcompany.com",
"password": "Troque-Esta-Senha-9",
"name": "Ana Lima",
"x_client_license_id": 7,
})
print(response.status_code, response.json())
Change a mailbox password
The panel generates a new password, changes the mailbox password and returns only the address of a secure link, which expires. The password never appears in the response.
curl -X POST -H "Authorization: Bearer $LUA_TOKEN" \
"https://painel.lua.email/api/v1/mailboxes/ana@yourcompany.com/password"
{
"success": true,
"data": {
"username": "ana@yourcompany.com",
"link": {"url": "https://pwpush.lua.email/p/abc123def456", "validade_dias": 3, "visualizacoes": 2, "com_frase": false},
"troca_no_proximo_acesso": true,
"dominio": "yourcompany.com"
}
}
Deactivate or activate a mailbox
Send "enabled": false to deactivate and true to activate. A mailbox without a license is not activated (409 caixa_sem_licenca), and anything blocked because of a billing issue is not reactivated (409 bloqueado_pelo_billing).
curl -X PUT \
-H "Authorization: Bearer $LUA_TOKEN" \
-H "Content-Type: application/json" \
-H "X-Lua-Motivo: Desligamento do colaborador" \
-d '{"enabled": false}' \
"https://painel.lua.email/api/v1/mailboxes/ana@yourcompany.com/active"
Mailbox settings
Forwarding, mailbox aliases, plan, service groups, access requirements, deleted messages and mobile devices. The fields of each operation are in the panel, under Support > API: documentation and testing.
| Method | Address | Permission | What it does |
|---|---|---|---|
GET | /api/v1/mailboxes/{mailbox}/forwarding | Reading | Looks up the addresses that receive a copy of the mailbox messages (forwarding). |
PUT | /api/v1/mailboxes/{mailbox}/forwarding | Mailboxes | Saves the full list of addresses that receive a copy of the mailbox messages (forwarding). |
GET | /api/v1/mailboxes/{mailbox}/aliases | Reading | Lists the aliases that point to the mailbox. |
POST | /api/v1/mailboxes/{mailbox}/aliases | Mailboxes | Adds an alias to the mailbox. |
DELETE | /api/v1/mailboxes/{mailbox}/aliases/{nickname} | Mailboxes | Removes an alias from the mailbox. |
GET | /api/v1/mailboxes/{mailbox}/license-swap/candidates | Reading | Lists the mailboxes this one can swap plans with. |
GET | /api/v1/mailboxes/{mailbox}/license-swap/preview | Reading | Shows the preview of a plan swap between two mailboxes. |
POST | /api/v1/mailboxes/{mailbox}/license-swap | Mailboxes | Swaps the plan between two mailboxes. |
GET | /api/v1/mailboxes/{mailbox}/service-groups | Mailboxes | Lists the mailbox service groups. |
PUT | /api/v1/mailboxes/{mailbox}/service-groups/{group_id} | Mailboxes | Adds the mailbox to a service group. |
DELETE | /api/v1/mailboxes/{mailbox}/service-groups/{group_id} | Mailboxes | Removes the mailbox from a service group. |
GET | /api/v1/mailboxes/{mailbox}/access-requirements | Mailboxes | Looks up the mailbox access requirements. |
PUT | /api/v1/mailboxes/{mailbox}/access-requirements | Mailboxes | Changes the mailbox access requirements. |
GET | /api/v1/mailboxes/{mailbox}/deleted-recovery | Mailboxes | Shows whether the mailbox has the Recover deleted messages feature and where it comes from. |
GET | /api/v1/mailboxes/{mailbox}/devices | Mailboxes | Lists the mobile devices of the mailbox. |
POST | /api/v1/mailboxes/{mailbox}/devices/{device_id}/remove | Mailboxes | Removes a device from synchronization, without erasing anything on it. |
POST | /api/v1/mailboxes/{mailbox}/devices/{device_id}/wipe | Mailboxes | Requests a remote wipe of the device, like the Wipe the device button. |
4. Email lists (aliases)
An email list is an address that delivers the message to several recipients. Requires the Lists and aliases permission.
| Method | Address | Permission | What it does |
|---|---|---|---|
GET | /api/v1/domains/{domain}/aliases | Lists and aliases | Lists the email lists of a domain. |
POST | /api/v1/domains/{domain}/aliases | Lists and aliases | Creates an email list. |
GET | /api/v1/aliases/{alias} | Lists and aliases | Looks up an email list. |
PUT | /api/v1/aliases/{alias} | Lists and aliases | Changes an email list. |
DELETE | /api/v1/aliases/{alias} | Lists and aliases | Removes an email list. |
curl -X POST \
-H "Authorization: Bearer $LUA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"address_local": "contato", "goto": ["maria@yourcompany.com", "ana@yourcompany.com"]}' \
"https://painel.lua.email/api/v1/domains/yourcompany.com/aliases"
response = call("POST", "/domains/yourcompany.com/aliases", json={
"address_local": "contato",
"goto": ["maria@yourcompany.com", "ana@yourcompany.com"],
})
print(response.status_code, response.json()["data"]["address"])
Each recipient in a domain hosted at lua.email must exist as a mailbox or as a list. The internal (the list receives only from internal senders) and senders_authhorized (senders allowed to write to the list) fields are optional.
5. Senders, blocked IP and postmaster
The lists of allowed (branca) and blocked (negra) senders apply to your domain. They require the Lists and aliases permission.
| Method | Address | Permission | What it does |
|---|---|---|---|
GET | /api/v1/domains/{domain}/listas/{list} | Lists and aliases | Shows the domain allow list ({list} = branca) or block list ({list} = negra). |
POST | /api/v1/domains/{domain}/listas/{list} | Lists and aliases | Adds a sender to the domain allowed or blocked list. |
DELETE | /api/v1/domains/{domain}/listas/{list}/{entry_id} | Lists and aliases | Removes a sender from the domain allow list or block list. |
GET | /api/v1/tools/ip/{ip}/bloqueio | Lists and aliases | Checks whether an IP address is blocked. |
GET | /api/v1/tools/ip/liberacoes | Lists and aliases | Lists the IP addresses unblocked for 24 hours. |
POST | /api/v1/tools/ip/liberacoes | Lists and aliases | Lifts the block on an IP address for 24 hours. |
DELETE | /api/v1/tools/ip/liberacoes/{ip} | Lists and aliases | Ends the unblock of an IP address before it expires. |
POST | /api/v1/postmaster/pedidos | Lists and aliases | Opens a request to the postmaster, for example to remove an IP address from a blocklist. |
GET | /api/v1/postmaster/pedidos/{protocol} | Lists and aliases | Looks up a request to the postmaster. |
curl -X POST \
-H "Authorization: Bearer $LUA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"origem": "fornecedor@exemplo.com.br"}' \
"https://painel.lua.email/api/v1/domains/yourcompany.com/listas/branca"
The origem is the email address or domain of the sender, and is required. The destino, a mailbox in your domain, is optional; without it, the rule applies to the whole domain. Adding a sender that is already on the list again returns 409.
Unblocking applies only to a public IP address that is blocked right now and where an account in your domain appeared in the last 7 days. Each customer can have up to 10 unblocks at the same time, and each one expires on its own after 24 hours.
6. DNS, alias domains and routing
Requires the DNS and routing permission. Records can be changed only while the domain DNS is active at Edgium; otherwise the response is 409 dns_fora_da_edgium and the query shows what to create at the current provider.
| Method | Address | Permission | What it does |
|---|---|---|---|
GET | /api/v1/domains/{domain}/dns | DNS and routing | Looks up the DNS records of the domain. |
GET | /api/v1/domains/{domain}/dns/expected | DNS and routing | Looks up the expected email records and the check against public DNS. |
PATCH | /api/v1/domains/{domain}/dns/records | DNS and routing | Creates, changes and deletes 1 to 50 DNS records in a single request: either everything is saved or nothing is. |
POST | /api/v1/domains/{domain}/dns/email/previa | DNS and routing | Shows the preview of the email records, without changing anything. |
POST | /api/v1/domains/{domain}/dns/email/aplicar | DNS and routing | Applies the email records to DNS. |
POST | /api/v1/domains/{domain}/dns/email/trocar-mx | DNS and routing | Changes the MX so that emails start arriving at lua.email. |
POST | /api/v1/domains/{domain}/dns/email/desfazer | DNS and routing | Undoes the last email action on DNS (applying the records or changing the MX). |
GET | /api/v1/domains/{domain}/alias-domains | DNS and routing | Lists the alias domains of a domain. |
POST | /api/v1/alias-domains | DNS and routing | Creates an alias domain. |
GET | /api/v1/alias-domains/{aliasdomain} | DNS and routing | Looks up an alias domain. |
PUT | /api/v1/alias-domains/{aliasdomain} | DNS and routing | Changes an alias domain. |
DELETE | /api/v1/alias-domains/{aliasdomain} | DNS and routing | Removes an alias domain. |
GET | /api/v1/domains/{domain}/email-transports | DNS and routing | Lists the per-email routings of a domain (addresses delivered to another email system). |
GET | /api/v1/email-transports/{transport_id} | DNS and routing | Looks up an email routing. |
Check the email records and apply them
The query returns, in data.esperados, what lua.email expects in DNS, together with the hash and the versao of the preview. To apply, send these two values; if the preview changed in the meantime, the response is 409 plano_mudou and carries the new hash.
check = call("GET", "/domains/yourcompany.com/dns/expected").json()["data"]
plan = check["esperados"]
print(check["estado_dns"], plan["resumo"])
response = call("POST", "/domains/yourcompany.com/dns/email/aplicar",
json={"plan_hash": plan["hash"], "versao": plan["versao"]})
print(response.status_code)
Changing the MX makes emails start arriving at lua.email. It requires the email records to be applied first and "confirmo": true in the body of /dns/email/trocar-mx. Without the confirmation, the response is 422 confirmacao_obrigatoria.
In a batch change, email records are protected: some require the confirm field and others change only through their own action. DMARC and SPF cannot be deleted. To check a change without saving it, send "dry_run": true.
7. Email logs
Shows message delivery for the domain and the spam filter analysis. Requires the Email logs or Read permission.
| Method | Address | Permission | What it does |
|---|---|---|---|
GET | /api/v1/domains/{domain}/logs/mensagens | Email logs | Looks up message delivery for the domain and the spam filter analysis. |
Without desde and ate, the query covers the last 24 hours. The maximum window is 7 days, within the last 180 days, in Brasília time. The filters are remetente, destinatario, endereco and message_id. The response does not include the total: request the next page while pagination.tem_proxima is true.
curl -H "Authorization: Bearer $LUA_TOKEN" \
"https://painel.lua.email/api/v1/domains/yourcompany.com/logs/mensagens?destinatario=maria@&desde=2026-11-09&ate=2026-11-10"
params = {"destinatario": "maria@", "desde": "2026-11-09", "ate": "2026-11-10", "per_page": 100}
body = call("GET", "/domains/yourcompany.com/logs/mensagens", params=params).json()
for item in body["data"]:
print(item["quando"], item["remetente"], item["status_texto"], item["caminho"])
8. Check, token and support history
| Method | Address | Permission | What it does |
|---|---|---|---|
GET | /api/v1/health | Any token | Checks that the API is working. No token needed. |
GET | /api/v1/token | Any token | Shows the user, permissions and validity of the token that made the call. |
DELETE | /api/v1/token | Any token | Revokes the token that made the call. |
GET | /api/v1/tokens | Any token | Lists your tokens, without the value. |
DELETE | /api/v1/tokens/{token_id} | Any token | Revokes one of your tokens. |
GET | /api/v1/support-history | Reading | Looks up the support history: what the support team and the integrations did on your domains. |
The operating check (/health) is the only operation that does not require a token. All the others, including those of the token itself, require the Authorization: Bearer header.