mail-server/api/v1/openapi.yml
2025-05-20 09:59:54 +02:00

2622 lines
82 KiB
YAML

# SPDX-FileCopyrightText: 2025 Stalwart Labs Ltd <hello@stalw.art>
#
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
openapi: 3.0.0
info:
title: Stalwart API
version: 1.0.0
servers:
- url: https://mail.example.org/api
description: Sample server
paths:
/oauth:
post:
summary: Obtain OAuth token
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
code:
type: string
permissions:
type: array
items:
type: string
version:
type: string
isEnterprise:
type: boolean
example:
data:
code: 4YmRFLu9Df1t4JO7Iffnuney4B8tVLAxjimdRxEg
permissions:
- webadmin-update
- spam-filter-update
- dkim-signature-get
- dkim-signature-create
- undelete
- fts-reindex
- purge-account
- purge-in-memory-store
- purge-data-store
- purge-blob-store
version: 0.11.0
isEnterprise: true
"401":
description: Unauthorized
content:
application/json:
schema:
type: object
properties:
type:
type: string
status:
type: number
title:
type: string
detail:
type: string
example:
type: about:blank
status: 401
title: Unauthorized
detail: You have to authenticate first.
requestBody:
content:
application/json:
schema:
type: object
properties:
type:
type: string
client_id:
type: string
redirect_uri:
type: string
nonce:
type: string
example:
type: code
client_id: webadmin
redirect_uri: stalwart://auth
nonce: ttsaXca3qx
/telemetry/metrics:
get:
summary: Fetch Telemetry Metrics
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
error:
type: string
details:
type: string
reason:
type: string
example:
error: other
details: No metrics store has been defined
reason:
You need to configure a metrics store in order to use this
feature.
parameters:
- name: after
in: query
required: false
schema:
type: string
/telemetry/live/metrics-token:
get:
summary: Obtain Metrics Telemetry token
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: string
example:
data: 2GO4RahIkSAms6S00R9BRsroo97ZdYTz4QVxFCOwGrGkr7zguP0AVyTMA/iha3Vz/////w8DhZi1+ALBmLX4AndlYg==
/telemetry/metrics/live:
get:
summary: Live Metrics
responses:
"200":
description: OK
content: {}
parameters:
- name: metrics
in: query
required: false
schema:
type: string
- name: interval
in: query
required: false
schema:
type: number
- name: token
in: query
required: false
schema:
type: string
/principal:
get:
summary: List Principals
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
items:
type: array
items: {}
total:
type: number
example:
data:
items: []
total: 0
parameters:
- name: page
in: query
required: false
schema:
type: number
- name: limit
in: query
required: false
schema:
type: number
- name: types
in: query
required: false
schema:
type: string
post:
summary: Create Principal
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: number
example:
data: 50
requestBody:
content:
application/json:
schema:
type: object
properties:
type:
type: string
quota:
type: number
name:
type: string
description:
type: string
secrets:
type: array
items: {}
emails:
type: array
items: {}
urls:
type: array
items: {}
memberOf:
type: array
items: {}
roles:
type: array
items: {}
lists:
type: array
items: {}
members:
type: array
items: {}
enabledPermissions:
type: array
items: {}
disabledPermissions:
type: array
items: {}
externalMembers:
type: array
items: {}
example:
type: domain
quota: 0
name: example.org
description: Example domain
secrets: []
emails: []
urls: []
memberOf: []
roles: []
lists: []
members: []
enabledPermissions: []
disabledPermissions: []
externalMembers: []
/dkim:
post:
summary: Create DKIM Signature
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
requestBody:
content:
application/json:
schema:
type: object
properties:
id:
type: object
nullable: true
algorithm:
type: string
domain:
type: string
selector:
type: object
nullable: true
example:
id:
algorithm: Ed25519
domain: example.org
selector:
/principal/{principal_id}:
get:
summary: Fetch Principal
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
id:
type: number
type:
type: string
secrets:
type: string
name:
type: string
quota:
type: number
description:
type: string
emails:
type: string
roles:
type: array
items:
type: string
lists:
type: array
items:
type: string
example:
data:
id: 90
type: individual
secrets: $6$ONjGT6nQtmPNaxw0$NNF5DXtPfOay2mfVnPJ0uQ77C.L3LNxXO/QMyphP/DzpODqbDBBGd4/gCnckYPQj3st6pqwY8/KeBsCJ.oe1Y1
name: jane
quota: 0
description: Jane Doe
emails: jane@example.org
roles:
- user
lists:
- all
parameters:
- name: principal_id
in: path
required: true
schema:
type: string
patch:
summary: Update Principal
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
parameters:
- name: principal_id
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: array
items:
type: object
properties:
action:
type: string
field:
type: string
value:
type: string
example:
- action: set
field: name
value: jane.doe
- action: set
field: description
value: Jane Mary Doe
- action: addItem
field: emails
value: jane-doe@example.org
- action: removeItem
field: emails
value: jane@example.org
delete:
summary: Delete Principal
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
parameters:
- name: principal_id
in: path
required: true
schema:
type: string
/queue/messages:
get:
summary: List Queued Messages
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
items:
type: array
items: {}
total:
type: number
status:
type: boolean
example:
data:
items: []
total: 0
status: true
parameters:
- name: page
in: query
required: false
schema:
type: number
- name: max-total
in: query
required: false
schema:
type: number
- name: limit
in: query
required: false
schema:
type: number
- name: values
in: query
required: false
schema:
type: number
patch:
summary: Reschedule Queued Messages
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: boolean
example:
data: true
parameters:
- name: filter
in: query
required: false
schema:
type: string
delete:
summary: Delete Queued Messages
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: boolean
example:
data: true
parameters:
- name: text
in: query
required: false
schema:
type: string
/queue/reports:
get:
summary: List Queued Reports
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
items:
type: array
items: {}
total:
type: number
example:
data:
items: []
total: 0
parameters:
- name: max-total
in: query
required: false
schema:
type: number
- name: limit
in: query
required: false
schema:
type: number
- name: page
in: query
required: false
schema:
type: number
/reports/dmarc:
get:
summary: List Incoming DMARC Reports
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
items:
type: array
items: {}
total:
type: number
example:
data:
items: []
total: 0
parameters:
- name: max-total
in: query
required: false
schema:
type: number
- name: limit
in: query
required: false
schema:
type: number
- name: page
in: query
required: false
schema:
type: number
/reports/tls:
get:
summary: List Incoming TLS Reports
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
items:
type: array
items: {}
total:
type: number
example:
data:
items: []
total: 0
parameters:
- name: limit
in: query
required: false
schema:
type: number
- name: max-total
in: query
required: false
schema:
type: number
- name: page
in: query
required: false
schema:
type: number
/reports/arf:
get:
summary: List Incoming ARF Reports
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
items:
type: array
items: {}
total:
type: number
example:
data:
items: []
total: 0
parameters:
- name: page
in: query
required: false
schema:
type: number
- name: limit
in: query
required: false
schema:
type: number
- name: max-total
in: query
required: false
schema:
type: number
/telemetry/traces:
get:
summary: List Stored Traces
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
error:
type: string
details:
type: string
example:
error: unsupported
details: No tracing store has been configured
parameters:
- name: type
in: query
required: false
schema:
type: string
- name: page
in: query
required: false
schema:
type: number
- name: limit
in: query
required: false
schema:
type: number
- name: values
in: query
required: false
schema:
type: number
/logs:
get:
summary: Quere Log Files
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
items:
type: array
items:
type: object
properties:
timestamp:
type: string
level:
type: string
event:
type: string
event_id:
type: string
details:
type: string
total:
type: number
example:
data:
items:
- timestamp: "2025-01-05T14:06:29Z"
level: TRACE
event: HTTP request body
event_id: http.request-body
details:
listenerId = "http", localPort = 1443, remoteIp = ::1,
remotePort = 57223, contents = "", size = 0
- timestamp: "2025-01-05T14:06:29Z"
level: TRACE
event: Write batch operation
event_id: store.data-write
details: elapsed = 0ms, total = 2
- timestamp: "2025-01-05T14:06:29Z"
level: TRACE
event: Expression evaluation result
event_id: eval.result
details:
listenerId = "http", localPort = 1443, remoteIp = ::1,
remotePort = 57223, id = "server.http.allowed-endpoint", result
= "Integer(200)"
- timestamp: "2025-01-05T14:06:29Z"
level: DEBUG
event: HTTP request URL
event_id: http.request-url
details:
listenerId = "http", localPort = 1443, remoteIp = ::1,
remotePort = 57223, url = "/api/logs?page=1&limit=50&"
- timestamp: "2025-01-05T14:06:23Z"
level: TRACE
event: HTTP response body
event_id: http.response-body
details:
listenerId = "http", localPort = 1443, remoteIp = ::1,
remotePort = 57223, contents = "{"error":"unsupported","details":"No
tracing store has been configured"}", code = 200, size = 72
- timestamp: "2025-01-05T14:06:23Z"
level: DEBUG
event: Management operation not supported
event_id: manage.not-supported
details:
listenerId = "http", localPort = 1443, remoteIp = ::1,
remotePort = 57223, details = No tracing store has been configured
- timestamp: "2025-01-05T14:06:23Z"
level: TRACE
event: HTTP request body
event_id: http.request-body
details:
listenerId = "http", localPort = 1443, remoteIp = ::1,
remotePort = 57223, contents = "", size = 0
- timestamp: "2025-01-05T14:06:23Z"
level: TRACE
event: Write batch operation
event_id: store.data-write
details: elapsed = 0ms, total = 2
- timestamp: "2025-01-05T14:06:23Z"
level: TRACE
event: Expression evaluation result
event_id: eval.result
details:
listenerId = "http", localPort = 1443, remoteIp = ::1,
remotePort = 57223, id = "server.http.allowed-endpoint", result
= "Integer(200)"
- timestamp: "2025-01-05T14:06:23Z"
level: DEBUG
event: HTTP request URL
event_id: http.request-url
details:
listenerId = "http", localPort = 1443, remoteIp = ::1,
remotePort = 57223, url = "/api/telemetry/traces?page=1&type=delivery.attempt-start&limit=10&values=1&"
total: 100
parameters:
- name: page
in: query
required: false
schema:
type: number
- name: limit
in: query
required: false
schema:
type: number
/spam-filter/train/spam:
post:
summary: Train Spam Filter as Spam
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
? "From: john@example.org\nTo: list@example.org\nSubject: Testing,
please ignore\nContent-Type: text/plain; charset"
: type: string
example:
? "From: john@example.org\nTo: list@example.org\nSubject: Testing, please
ignore\nContent-Type: text/plain; charset"
: "\"utf-8\"\nContent-Transfer-Encoding: 8bit\n\nTesting 1, 2, 3\n"
/spam-filter/train/ham:
post:
summary: Train Spam Filter as Ham
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
? "From: john@example.org\nTo: list@example.org\nSubject: Testing,
please ignore\nContent-Type: text/plain; charset"
: type: string
example:
? "From: john@example.org\nTo: list@example.org\nSubject: Testing, please
ignore\nContent-Type: text/plain; charset"
: "\"utf-8\"\nContent-Transfer-Encoding: 8bit\n\nTesting 1, 2, 3\n"
/spam-filter/train/spam/{account_id}:
post:
summary: Train Account's Spam Filter as Spam
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
parameters:
- name: account_id
in: path
required: true
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
? "From: john@example.org\nTo: list@example.org\nSubject: Testing,
please ignore\nContent-Type: text/plain; charset"
: type: string
example:
? "From: john@example.org\nTo: list@example.org\nSubject: Testing, please
ignore\nContent-Type: text/plain; charset"
: "\"utf-8\"\nContent-Transfer-Encoding: 8bit\n\nTesting 1, 2, 3\n"
/spam-filter/train/ham/{account_id}:
post:
summary: Train Account's Spam Filter as Ham
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
parameters:
- name: account_id
in: path
required: true
schema:
type: string
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
? "From: john@example.org\nTo: list@example.org\nSubject: Testing,
please ignore\nContent-Type: text/plain; charset"
: type: string
example:
? "From: john@example.org\nTo: list@example.org\nSubject: Testing, please
ignore\nContent-Type: text/plain; charset"
: "\"utf-8\"\nContent-Transfer-Encoding: 8bit\n\nTesting 1, 2, 3\n"
/spam-filter/classify:
post:
summary: Test Spam Filter Classification
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
score:
type: number
tags:
type: object
properties:
FROM_NO_DN:
type: object
properties:
action:
type: string
value:
type: number
SOURCE_ASN_15169:
type: object
properties:
action:
type: string
value:
type: number
SOURCE_COUNTRY_US:
type: object
properties:
action:
type: string
value:
type: number
MISSING_DATE:
type: object
properties:
action:
type: string
value:
type: number
FROMHOST_NORES_A_OR_MX:
type: object
properties:
action:
type: string
value:
type: number
MISSING_MIME_VERSION:
type: object
properties:
action:
type: string
value:
type: number
FORGED_SENDER:
type: object
properties:
action:
type: string
value:
type: number
SPF_NA:
type: object
properties:
action:
type: string
value:
type: number
X_HDR_TO:
type: object
properties:
action:
type: string
value:
type: number
HELO_IPREV_MISMATCH:
type: object
properties:
action:
type: string
value:
type: number
X_HDR_CONTENT_TYPE:
type: object
properties:
action:
type: string
value:
type: number
AUTH_NA:
type: object
properties:
action:
type: string
value:
type: number
FORGED_RECIPIENTS:
type: object
properties:
action:
type: string
value:
type: number
RBL_SENDERSCORE_REPUT_BLOCKED:
type: object
properties:
action:
type: string
value:
type: number
RCVD_COUNT_ZERO:
type: object
properties:
action:
type: string
value:
type: number
X_HDR_SUBJECT:
type: object
properties:
action:
type: string
value:
type: number
X_HDR_FROM:
type: object
properties:
action:
type: string
value:
type: number
RCPT_COUNT_ONE:
type: object
properties:
action:
type: string
value:
type: number
MISSING_MID:
type: object
properties:
action:
type: string
value:
type: number
TO_DOM_EQ_FROM_DOM:
type: object
properties:
action:
type: string
value:
type: number
ARC_NA:
type: object
properties:
action:
type: string
value:
type: number
RCVD_TLS_LAST:
type: object
properties:
action:
type: string
value:
type: number
X_HDR_CONTENT_TRANSFER_ENCODING:
type: object
properties:
action:
type: string
value:
type: number
HELO_NORES_A_OR_MX:
type: object
properties:
action:
type: string
value:
type: number
TO_DN_NONE:
type: object
properties:
action:
type: string
value:
type: number
FROM_NEQ_ENV_FROM:
type: object
properties:
action:
type: string
value:
type: number
DMARC_NA:
type: object
properties:
action:
type: string
value:
type: number
SINGLE_SHORT_PART:
type: object
properties:
action:
type: string
value:
type: number
DKIM_NA:
type: object
properties:
action:
type: string
value:
type: number
disposition:
type: object
properties:
action:
type: string
value:
type: string
example:
data:
score: 12.7
tags:
FROM_NO_DN:
action: allow
value: 0.0
SOURCE_ASN_15169:
action: allow
value: 0.0
SOURCE_COUNTRY_US:
action: allow
value: 0.0
MISSING_DATE:
action: allow
value: 1.0
FROMHOST_NORES_A_OR_MX:
action: allow
value: 1.5
MISSING_MIME_VERSION:
action: allow
value: 2.0
FORGED_SENDER:
action: allow
value: 0.3
SPF_NA:
action: allow
value: 0.0
X_HDR_TO:
action: allow
value: 0.0
HELO_IPREV_MISMATCH:
action: allow
value: 1.0
X_HDR_CONTENT_TYPE:
action: allow
value: 0.0
AUTH_NA:
action: allow
value: 1.0
FORGED_RECIPIENTS:
action: allow
value: 2.0
RBL_SENDERSCORE_REPUT_BLOCKED:
action: allow
value: 0.0
RCVD_COUNT_ZERO:
action: allow
value: 0.1
X_HDR_SUBJECT:
action: allow
value: 0.0
X_HDR_FROM:
action: allow
value: 0.0
RCPT_COUNT_ONE:
action: allow
value: 0.0
MISSING_MID:
action: allow
value: 2.5
TO_DOM_EQ_FROM_DOM:
action: allow
value: 0.0
ARC_NA:
action: allow
value: 0.0
RCVD_TLS_LAST:
action: allow
value: 0.0
X_HDR_CONTENT_TRANSFER_ENCODING:
action: allow
value: 0.0
HELO_NORES_A_OR_MX:
action: allow
value: 0.3
TO_DN_NONE:
action: allow
value: 0.0
FROM_NEQ_ENV_FROM:
action: allow
value: 0.0
DMARC_NA:
action: allow
value: 1.0
SINGLE_SHORT_PART:
action: allow
value: 0.0
DKIM_NA:
action: allow
value: 0.0
disposition:
action: allow
value:
"X-Spam-Result: ARC_NA (0.00),\r\n\tDKIM_NA (0.00),\r\n
\tFROM_NEQ_ENV_FROM (0.00),\r\n\tFROM_NO_DN (0.00),\r\n\tRBL_SENDERSCORE_REPUT_BLOCKED
(0.00),\r\n\tRCPT_COUNT_ONE (0.00),\r\n\tRCVD_TLS_LAST (0.00),\r
\n\tSINGLE_SHORT_PART (0.00),\r\n\tSPF_NA (0.00),\r\n\tTO_DN_NONE
(0.00),\r\n\tTO_DOM_EQ_FROM_DOM (0.00),\r\n\tRCVD_COUNT_ZERO
(0.10),\r\n\tFORGED_SENDER (0.30),\r\n\tHELO_NORES_A_OR_MX (0.30),\r
\n\tAUTH_NA (1.00),\r\n\tDMARC_NA (1.00),\r\n\tHELO_IPREV_MISMATCH
(1.00),\r\n\tMISSING_DATE (1.00),\r\n\tFROMHOST_NORES_A_OR_MX
(1.50),\r\n\tFORGED_RECIPIENTS (2.00),\r\n\tMISSING_MIME_VERSION
(2.00),\r\n\tMISSING_MID (2.50)\r\nX-Spam-Status: Yes, score=12.70\r\
\n"
requestBody:
content:
application/json:
schema:
type: object
properties:
message:
type: string
remoteIp:
type: string
ehloDomain:
type: string
authenticatedAs:
type: object
nullable: true
isTls:
type: boolean
envFrom:
type: string
envFromFlags:
type: number
envRcptTo:
type: array
items:
type: string
example:
message:
"From: john@example.org\nTo: list@example.org\nSubject: Testing,
please ignore\nContent-Type: text/plain; charset=\"utf-8\"\nContent-Transfer-Encoding:
8bit\n\nTesting 1, 2, 3\n"
remoteIp: 8.8.8.8
ehloDomain: foo.org
authenticatedAs:
isTls: true
envFrom: bill@foo.org
envFromFlags: 0
envRcptTo:
- john@example.org
/troubleshoot/token:
get:
summary: Obtain a Troubleshooting Token
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: string
example:
data: +bS1rCUcrjoEtl9f7Vz1P6daqVs4nywxa56bHltPIASijRFrj1JrwvHxJCWphPKs/////w8E8p21+AKunrX4AndlYg==
/troubleshoot/delivery/{recipient}:
get:
summary: Run Delivery Troubleshooting
responses:
"200":
description: OK
content: {}
parameters:
- name: recipient
in: path
required: true
schema:
type: string
- name: token
in: query
required: false
schema:
type: string
/troubleshoot/dmarc:
post:
summary: Run DMARC Troubleshooting
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
spfEhloDomain:
type: string
spfEhloResult:
type: object
properties:
type:
type: string
spfMailFromDomain:
type: string
spfMailFromResult:
type: object
properties:
type:
type: string
details:
type: object
nullable: true
ipRevResult:
type: object
properties:
type:
type: string
ipRevPtr:
type: array
items:
type: string
dkimResults:
type: array
items: {}
dkimPass:
type: boolean
arcResult:
type: object
properties:
type:
type: string
dmarcResult:
type: object
properties:
type:
type: string
dmarcPass:
type: boolean
dmarcPolicy:
type: string
elapsed:
type: number
example:
data:
spfEhloDomain: mx.google.com
spfEhloResult:
type: none
spfMailFromDomain: google.com
spfMailFromResult:
type: softFail
details:
ipRevResult:
type: pass
ipRevPtr:
- dns.google.
dkimResults: []
dkimPass: false
arcResult:
type: none
dmarcResult:
type: none
dmarcPass: false
dmarcPolicy: reject
elapsed: 200
requestBody:
content:
application/json:
schema:
type: object
properties:
remoteIp:
type: string
ehloDomain:
type: string
mailFrom:
type: string
body:
type: string
example:
remoteIp: 8.8.8.8
ehloDomain: mx.google.com
mailFrom: john@google.com
body:
"From: john@example.org\nTo: list@example.org\nSubject: Testing,
please ignore\nContent-Type: text/plain; charset=\"utf-8\"\nContent-Transfer-Encoding:
8bit\n\nTesting 1, 2, 3\n"
/reload:
get:
summary: Reload Settings
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
warnings:
type: object
properties: {}
errors:
type: object
properties: {}
example:
data:
warnings: {}
errors: {}
parameters:
- name: dry-run
in: query
required: false
schema:
type: string
/update/spam-filter:
get:
summary: Update Spam Filter
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
/update/webadmin:
get:
summary: Update WebAdmin
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
/store/reindex:
get:
summary: Request FTS Reindex
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
/store/purge/in-memory/default/bayes-global:
get:
summary: Delete Global Bayes Model
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
/settings/keys:
get:
summary: List Settings by Key
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
lookup.default.hostname:
type: string
example:
data:
lookup.default.hostname: mx.fr.email
parameters:
- name: prefixes
in: query
required: false
schema:
type: string
- name: keys
in: query
required: false
schema:
type: string
/settings/group:
get:
summary: List Settings by Group
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
total:
type: number
items:
type: array
items:
type: object
properties:
_id:
type: string
bind:
type: string
protocol:
type: string
example:
data:
total: 11
items:
- _id: http
bind: "[::]:1443"
protocol: http
- bind: "[::]:443"
_id: https
protocol: http
tls.implicit: "true"
- protocol: imap
bind: "[::]:143"
_id: imap
- bind: "[::]:1143"
tls.implicit: "false"
_id: imapnotls
protocol: imap
proxy.override: "false"
tls.override: "false"
tls.enable: "false"
socket.override: "false"
- bind: "[::]:993"
tls.implicit: "true"
protocol: imap
_id: imaptls
- bind: "[::]:110"
protocol: pop3
_id: pop3
- tls.implicit: "true"
_id: pop3s
protocol: pop3
bind: "[::]:995"
- protocol: managesieve
_id: sieve
bind: "[::]:4190"
- bind: "[::]:25"
_id: smtp
protocol: smtp
- _id: submission
bind: "[::]:587"
protocol: smtp
parameters:
- name: limit
in: query
required: false
schema:
type: number
- name: page
in: query
required: false
schema:
type: number
- name: suffix
in: query
required: false
schema:
type: string
- name: prefix
in: query
required: false
schema:
type: string
/settings/list:
get:
summary: List Settings
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
total:
type: number
items:
type: object
properties:
enable:
type: string
format:
type: string
limits.entries:
type: string
limits.entry-size:
type: string
limits.size:
type: string
refresh:
type: string
retry:
type: string
timeout:
type: string
url:
type: string
example:
data:
total: 9
items:
enable: "true"
format: list
limits.entries: "100000"
limits.entry-size: "512"
limits.size: "104857600"
refresh: 12h
retry: 1h
timeout: 30s
url: https://openphish.com/feed.txt
parameters:
- name: prefix
in: query
required: false
schema:
type: string
/settings:
post:
summary: Update Settings
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
requestBody:
content:
application/json:
schema:
type: array
items:
type: object
properties:
type:
type: string
prefix:
type: string
example:
- type: clear
prefix: spam-filter.rule.stwt_arc_signed.
/account/crypto:
get:
summary: Obtain Encryption-at-Rest Settings
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
type:
type: string
example:
data:
type: disabled
post:
summary: Update Encryption-at-Rest Settings
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: number
example:
data: 1
requestBody:
content:
application/json:
schema:
type: object
properties:
type:
type: string
algo:
type: string
certs:
type: string
example:
type: pGP
algo: Aes256
certs:
"-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\n=0TDv\n-----END PGP
PUBLIC KEY BLOCK-----\n\n\n"
/account/auth:
get:
summary: Obtain Account Authentication Settings
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
otpEnabled:
type: boolean
appPasswords:
type: array
items: {}
example:
data:
otpEnabled: false
appPasswords: []
post:
summary: Update Account Authentication Settings
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
error:
type: string
details:
type: string
reason:
type: object
nullable: true
example:
error: other
details: Fallback administrator accounts do not support 2FA or AppPasswords
reason:
"401":
description: Unauthorized
content:
application/json:
schema:
type: object
properties:
type:
type: string
status:
type: number
title:
type: string
detail:
type: string
example:
type: about:blank
status: 401
title: Unauthorized
detail: You have to authenticate first.
requestBody:
content:
application/json:
schema:
type: array
items:
type: object
properties:
type:
type: string
name:
type: string
password:
type: string
example:
- type: addAppPassword
name: dGVzdCQyMDI1LTAxLTA1VDE0OjEyOjUxLjg0NyswMDowMA==
password: $6$4M/5LmG7b13r0cdE$6zb.i6wJ3pAQHA2MRHkKg0t8bgSYb2IeqiIU115t.NugwW6VXifE0VKI5n2BQUNwdeDMUzaX82TmhuVVgC0Gx1
/reload/:
get:
summary: Reload Settings
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
warnings:
type: object
properties: {}
errors:
type: object
properties: {}
example:
data:
warnings: {}
errors: {}
/queue/status/stop:
patch:
summary: Stop Queue Processing
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: boolean
example:
data: true
/queue/status/start:
patch:
summary: Resume Queue Processing
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: boolean
example:
data: false
/queue/messages/{message_id}:
get:
summary: Obtain Queued Message Details
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
id:
type: number
return_path:
type: string
domains:
type: array
items:
type: object
properties:
name:
type: string
status:
type: string
recipients:
type: array
items:
type: object
properties:
address:
type: string
status:
type: string
retry_num:
type: number
next_retry:
type: string
next_notify:
type: string
expires:
type: string
created:
type: string
size:
type: number
blob_hash:
type: string
example:
data:
id: 217700302698266624
return_path: pepe@pepe.com
domains:
- name: example.org
status: scheduled
recipients:
- address: john@example.org
status: scheduled
retry_num: 0
next_retry: "2025-01-05T14:33:15Z"
next_notify: "2025-01-06T14:33:15Z"
expires: "2025-01-10T14:33:15Z"
created: "2025-01-05T14:33:15Z"
size: 1451
blob_hash: ykrZ_KghvdG2AdjH4AZajkSvZvcsxP_oI2HEZvw-tS0
"404":
description: Not Found
content:
application/json:
schema:
type: object
properties:
type:
type: string
status:
type: number
title:
type: string
detail:
type: string
example:
type: about:blank
status: 404
title: Not Found
detail: The requested resource does not exist on this server.
parameters:
- name: message_id
in: path
required: true
schema:
type: string
patch:
summary: Reschedule Delivery of Queued Message
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: boolean
example:
data: true
parameters:
- name: message_id
in: path
required: true
schema:
type: string
delete:
summary: Cancel Delivery of Queued Message
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: boolean
example:
data: true
parameters:
- name: message_id
in: path
required: true
schema:
type: string
/store/blobs/{blob_id}:
get:
summary: Fetch Blob by ID
responses:
"200":
description: OK
content: {}
parameters:
- name: blob_id
in: path
required: true
schema:
type: string
- name: limit
in: query
required: false
schema:
type: number
/telemetry/trace/{trace_id}:
get:
summary: Obtain Trace Details
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
properties:
text:
type: string
details:
type: string
createdAt:
type: string
type:
type: string
data:
type: object
properties:
listenerId:
type: string
localPort:
type: number
remoteIp:
type: string
remotePort:
type: number
example:
data:
- text: SMTP connection started
details: A new SMTP connection was started
createdAt: "2025-01-05T14:34:50Z"
type: smtp.connection-start
data:
listenerId: smtp
localPort: 25
remoteIp: ::1
remotePort: 57513
- text: SMTP EHLO command
details: The remote server sent an EHLO command
createdAt: "2025-01-05T14:34:50Z"
type: smtp.ehlo
data:
domain: test.eml
- text: SPF EHLO check failed
details: EHLO identity failed SPF check
createdAt: "2025-01-05T14:34:50Z"
type: smtp.spf-ehlo-fail
data:
domain: test.eml
result:
type: spf.none
text: No SPF record
details: No SPF record was found
data: {}
elapsed: 24
- text: IPREV check passed
details: Reverse IP check passed
createdAt: "2025-01-05T14:34:50Z"
type: smtp.iprev-pass
data:
domain: test.eml
result:
type: iprev.pass
text: IPREV check passed
details: The IPREV check has passed
data:
details:
- localhost.
elapsed: 0
- text: SPF From check failed
details: MAIL FROM identity failed SPF check
createdAt: "2025-01-05T14:34:50Z"
type: smtp.spf-from-fail
data:
domain: test.eml
from: pepe@pepe.com
result:
type: spf.none
text: No SPF record
details: No SPF record was found
data: {}
elapsed: 18
- text: SMTP MAIL FROM command
details: The remote client sent a MAIL FROM command
createdAt: "2025-01-05T14:34:50Z"
type: smtp.mail-from
data:
from: pepe@pepe.com
- text: SMTP RCPT TO command
details: The remote client sent an RCPT TO command
createdAt: "2025-01-05T14:34:50Z"
type: smtp.rcpt-to
data:
to: john@example.org
- text: DKIM verification failed
details: Failed to verify DKIM signature
createdAt: "2025-01-05T14:34:50Z"
type: smtp.dkim-fail
data:
strict: false
result: []
elapsed: 0
- text: ARC verification passed
details: Successful ARC verification
createdAt: "2025-01-05T14:34:50Z"
type: smtp.arc-pass
data:
strict: false
result:
type: dkim.none
text: No DKIM signature
details: No DKIM signature was found
data: {}
elapsed: 0
- text: DMARC check failed
details: Failed to verify DMARC policy
createdAt: "2025-01-05T14:34:50Z"
type: smtp.dmarc-fail
data:
strict: false
domain: example.org
policy: reject
result:
type: dmarc.none
text: No DMARC record
details: No DMARC record was found
data: {}
elapsed: 0
parameters:
- name: trace_id
in: path
required: true
schema:
type: string
/telemetry/live/tracing-token:
get:
summary: Request a Tracing Token
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: string
example:
data: VLxkixOwgDF8Frj0wi8kPhx3SpzKqtsDvbo25wgKw2tBIz/O8La0dwioQw9pN11c/////w8Ctau1+ALxq7X4AndlYg==
/telemetry/traces/live:
get:
summary: Start Live Tracing
responses:
"200":
description: OK
content: {}
parameters:
- name: filter
in: query
required: false
schema:
type: string
- name: token
in: query
required: false
schema:
type: string
/dns/records/{domain}:
get:
summary: Obtain DNS Records for Domain
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
properties:
type:
type: string
name:
type: string
content:
type: string
example:
data:
- type: MX
name: example.org.
content: 10 mx.fr.email.
- type: CNAME
name: mail.example.org.
content: mx.fr.email.
- type: TXT
name: 202501e._domainkey.example.org.
content: v=DKIM1; k=ed25519; h=sha256; p=82LqzMGRHEBI2HGDogjojWGz+Crrv0TAi8pcaOBd1vw=
- type: TXT
name: 202501r._domainkey.example.org.
content: v=DKIM1; k=rsa; h=sha256;
p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1qtCbIlrZffIqm7gHqpihPUlxOq1zD6K3j1RO/enhkZRp5dEdCqcLbyFk5d+rqRsVIWwUZiU4HXHWqMTN1hlKojUlzmU1JYtlHRMwtM5vN4mzG4x1KA0i8ZHxkahE8ITsP+kPByDF9x0vAySHXpyErNXq3BeFyu/VW+6X+fmUW6x39PfWq7kQQTcwU0Ogo447oJfmAX9H4Z+/cD5WJVNiLgvLY6faVgoXm0mJJjRU5xoEStXoUcKwrwbl7G3K7JfxtmWsgEn97auV6v4he2LRRfTxbY9smkqUtcJs61E9iyyYroJv0iRda2pv71qg8e4wTb2sqBloZv/F2FZQhM+wIDAQAB
- type: TXT
name: example.org.
content: v=spf1 mx ra=postmaster -all
- type: SRV
name: _jmap._tcp.example.org.
content: 0 1 443 mx.fr.email.
- type: SRV
name: _imaps._tcp.example.org.
content: 0 1 993 mx.fr.email.
- type: SRV
name: _imap._tcp.example.org.
content: 0 1 143 mx.fr.email.
- type: SRV
name: _imap._tcp.example.org.
content: 0 1 1143 mx.fr.email.
- type: SRV
name: _pop3s._tcp.example.org.
content: 0 1 995 mx.fr.email.
parameters:
- name: domain
in: path
required: true
schema:
type: string
/store/purge/account/{account_id}:
get:
summary: Purge Account
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
parameters:
- name: account_id
in: path
required: true
schema:
type: string
/store/purge/in-memory/default/bayes-account/{account_id}:
get:
summary: Delete Bayes Model for Account
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
parameters:
- name: account_id
in: path
required: true
schema:
type: string
/store/undelete/{account_id}:
get:
summary: List Deleted Messages
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
items:
type: array
items: {}
total:
type: number
example:
data:
items: []
total: 0
parameters:
- name: account_id
in: path
required: true
schema:
type: string
- name: limit
in: query
required: false
schema:
type: number
- name: page
in: query
required: false
schema:
type: number
post:
summary: Undelete Messages
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
properties:
type:
type: string
example:
data:
- type: success
parameters:
- name: account_id
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: array
items:
type: object
properties:
hash:
type: string
collection:
type: string
restoreTime:
type: string
cancelDeletion:
type: string
example:
- hash: 9pDYGrkDlLYuBNl062qhi0wStnDYyq4ZWalnj2vXbLY
collection: email
restoreTime: "2025-01-05T14:50:13Z"
cancelDeletion: "2025-02-04T14:50:13Z"
/queue/status:
get:
summary: Obtain Queue Status
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: boolean
example:
data: true
/store/purge/blob:
get:
summary: Purge Blob Store
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
/store/purge/data:
get:
summary: Purge Data Store
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
/store/purge/in-memory:
get:
summary: Purge In-Memory Store
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
/store/purge/account:
get:
summary: Purge All Accounts
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
nullable: true
example:
data:
/store/uids/{account_id}:
delete:
summary: Reset IMAP UIDs for Account
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: number
example:
data:
- 0
- 0
parameters:
- name: account_id
in: path
required: true
schema:
type: string