Files
Stalwart/api/v1/openapi.yml
Aaron Dewes 4b3b158ed3 Add license details to OpenAPI schema (#1483)
This would make it easier for 3rd parties to integrate with Stalwart by being clear about licensing. I'm not sure if you want this license or want to release this file specifically under a more permissive license (MIT license would make sense here in my opinion, because it's just an API schema).
2025-05-12 16:53:18 +02:00

2623 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 Mail Server 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