happyDeliver/api/openapi.yaml
Pierre-Olivier Mercier dfc0eeb323
All checks were successful
continuous-integration/drone/push Build is passing
New route to perform a new analysis of the email
2025-10-20 19:33:23 +07:00

576 lines
16 KiB
YAML

openapi: 3.0.3
info:
title: happyDeliver API
description: Email Deliverability Testing Platform API
version: 0.1.0
contact:
name: happyDomain team
url: https://github.com/happyDomain/happydeliver
email: contact+api@happydomain.org
license:
name: GNU Affero General Public License v3.0 or later
url: https://spdx.org/licenses/AGPL-3.0-or-later.html
servers:
- url: http://localhost:8080/api
description: Local development server
- url: https://api.example.com/api
description: Production server
tags:
- name: tests
description: Test management operations
- name: reports
description: Report retrieval operations
- name: health
description: Service health and status
paths:
/test:
post:
tags:
- tests
summary: Create a new deliverability test
description: Generates a unique test email address for sending test emails. No database record is created until an email is received.
operationId: createTest
responses:
'201':
description: Test email address generated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/TestResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/test/{id}:
get:
tags:
- tests
summary: Get test status
description: Check if a report exists for the given test ID (base32-encoded). Returns pending if no report exists, analyzed if a report is available.
operationId: getTest
parameters:
- name: id
in: path
required: true
schema:
type: string
pattern: '^[a-z0-9-]+$'
description: Base32-encoded test ID (with hyphens)
responses:
'200':
description: Test status retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Test'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/report/{id}:
get:
tags:
- reports
summary: Get detailed report
description: Retrieve comprehensive deliverability analysis report
operationId: getReport
parameters:
- name: id
in: path
required: true
schema:
type: string
pattern: '^[a-z0-9-]+$'
description: Base32-encoded test ID (with hyphens)
responses:
'200':
description: Report retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Report'
'404':
description: Report not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/report/{id}/raw:
get:
tags:
- reports
summary: Get raw annotated email
description: Retrieve the original email with headers added by filters
operationId: getRawEmail
parameters:
- name: id
in: path
required: true
schema:
type: string
pattern: '^[a-z0-9-]+$'
description: Base32-encoded test ID (with hyphens)
responses:
'200':
description: Raw email retrieved successfully
content:
text/plain:
schema:
type: string
'404':
description: Email not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/report/{id}/reanalyze:
post:
tags:
- reports
summary: Reanalyze email and regenerate report
description: Re-run the analysis on the stored raw email to regenerate the report with the latest analyzer version. This is useful after analyzer improvements or bug fixes.
operationId: reanalyzeReport
parameters:
- name: id
in: path
required: true
schema:
type: string
pattern: '^[a-z0-9-]+$'
description: Base32-encoded test ID (with hyphens)
responses:
'200':
description: Report regenerated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Report'
'404':
description: Email not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal server error during reanalysis
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/status:
get:
tags:
- health
summary: Service health check
description: Get service health status and component versions
operationId: getStatus
responses:
'200':
description: Service status
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
components:
schemas:
Test:
type: object
required:
- id
- email
- status
properties:
id:
type: string
pattern: '^[a-z0-9-]+$'
description: Unique test identifier (base32-encoded with hyphens)
example: "krfwg4z-amrqw4z-zmorsw2-djmfzgk-3a"
email:
type: string
format: email
description: Unique test email address
example: "test-krfwg4z-amrqw4z-zmorsw2-djmfzgk-3a@example.com"
status:
type: string
enum: [pending, analyzed]
description: Current test status (pending = no report yet, analyzed = report available)
example: "analyzed"
TestResponse:
type: object
required:
- id
- email
- status
properties:
id:
type: string
pattern: '^[a-z0-9-]+$'
description: Unique test identifier (base32-encoded with hyphens)
example: "krfwg4z-amrqw4z-zmorsw2-djmfzgk-3a"
email:
type: string
format: email
example: "test-krfwg4z-amrqw4z-zmorsw2-djmfzgk-3a@example.com"
status:
type: string
enum: [pending]
example: "pending"
message:
type: string
example: "Send your test email to the address above"
Report:
type: object
required:
- id
- test_id
- score
- grade
- checks
- created_at
properties:
id:
type: string
pattern: '^[a-z0-9-]+$'
description: Report identifier (base32-encoded with hyphens)
test_id:
type: string
pattern: '^[a-z0-9-]+$'
description: Associated test ID (base32-encoded with hyphens)
score:
type: number
format: float
minimum: 0
maximum: 100
description: Overall deliverability score as percentage (0-100)
example: 85
grade:
type: string
enum: [A+, A, B, C, D, E, F]
description: Letter grade representation of the score (A+ is best, F is worst)
example: "A"
summary:
$ref: '#/components/schemas/ScoreSummary'
checks:
type: array
items:
$ref: '#/components/schemas/Check'
authentication:
$ref: '#/components/schemas/AuthenticationResults'
spamassassin:
$ref: '#/components/schemas/SpamAssassinResult'
dns_records:
type: array
items:
$ref: '#/components/schemas/DNSRecord'
blacklists:
type: array
items:
$ref: '#/components/schemas/BlacklistCheck'
raw_headers:
type: string
description: Raw email headers
created_at:
type: string
format: date-time
ScoreSummary:
type: object
required:
- authentication_score
- spam_score
- blacklist_score
- content_score
- header_score
properties:
authentication_score:
type: number
format: float
minimum: 0
maximum: 100
description: SPF/DKIM/DMARC score (in percentage)
example: 28
spam_score:
type: number
format: float
minimum: 0
maximum: 100
description: SpamAssassin score (in percentage)
example: 15
blacklist_score:
type: number
format: float
minimum: 0
maximum: 100
description: Blacklist check score (in percentage)
example: 20
content_score:
type: number
format: float
minimum: 0
maximum: 100
description: Content quality score (in percentage)
example: 18
header_score:
type: number
format: float
minimum: 0
maximum: 100
description: Header quality score (in percentage)
example: 9
Check:
type: object
required:
- category
- name
- status
- score
- grade
- message
properties:
category:
type: string
enum: [authentication, dns, content, blacklist, headers, spam]
description: Check category
example: "authentication"
name:
type: string
description: Check name
example: "DKIM Signature"
status:
type: string
enum: [pass, fail, warn, info, error]
description: Check result status
example: "pass"
score:
type: number
format: float
description: Points contributed to total score
example: 10
grade:
type: string
enum: [A+, A, B, C, D, E, F]
description: Letter grade representation of the score (A+ is best, F is worst)
example: "A"
message:
type: string
description: Human-readable result message
example: "DKIM signature is valid"
details:
type: string
description: Additional details (may be JSON)
severity:
type: string
enum: [critical, high, medium, low, info]
description: Issue severity
example: "info"
advice:
type: string
description: Remediation advice
example: "Your DKIM configuration is correct"
AuthenticationResults:
type: object
properties:
spf:
$ref: '#/components/schemas/AuthResult'
dkim:
type: array
items:
$ref: '#/components/schemas/AuthResult'
dmarc:
$ref: '#/components/schemas/AuthResult'
bimi:
$ref: '#/components/schemas/AuthResult'
arc:
$ref: '#/components/schemas/ARCResult'
AuthResult:
type: object
required:
- result
properties:
result:
type: string
enum: [pass, fail, none, neutral, softfail, temperror, permerror]
description: Authentication result
example: "pass"
domain:
type: string
description: Domain being authenticated
example: "example.com"
selector:
type: string
description: DKIM selector (for DKIM only)
example: "default"
details:
type: string
description: Additional details about the result
ARCResult:
type: object
required:
- result
properties:
result:
type: string
enum: [pass, fail, none]
description: Overall ARC chain validation result
example: "pass"
chain_valid:
type: boolean
description: Whether the ARC chain signatures are valid
example: true
chain_length:
type: integer
description: Number of ARC sets in the chain
example: 2
details:
type: string
description: Additional details about ARC validation
example: "ARC chain valid with 2 intermediaries"
SpamAssassinResult:
type: object
required:
- score
- required_score
- is_spam
properties:
score:
type: number
format: float
description: SpamAssassin spam score
example: 2.3
required_score:
type: number
format: float
description: Threshold for spam classification
example: 5.0
is_spam:
type: boolean
description: Whether message is classified as spam
example: false
tests:
type: array
items:
type: string
description: List of triggered SpamAssassin tests
example: ["BAYES_00", "DKIM_SIGNED"]
report:
type: string
description: Full SpamAssassin report
DNSRecord:
type: object
required:
- domain
- record_type
- status
properties:
domain:
type: string
description: Domain name
example: "example.com"
record_type:
type: string
enum: [MX, SPF, DKIM, DMARC, BIMI]
description: DNS record type
example: "SPF"
status:
type: string
enum: [found, missing, invalid]
description: Record status
example: "found"
value:
type: string
description: Record value
example: "v=spf1 include:_spf.example.com ~all"
BlacklistCheck:
type: object
required:
- ip
- rbl
- listed
properties:
ip:
type: string
description: IP address checked
example: "192.0.2.1"
rbl:
type: string
description: RBL/DNSBL name
example: "zen.spamhaus.org"
listed:
type: boolean
description: Whether IP is listed
example: false
response:
type: string
description: RBL response code or message
example: "127.0.0.2"
Status:
type: object
required:
- status
- version
properties:
status:
type: string
enum: [healthy, degraded, unhealthy]
description: Overall service status
example: "healthy"
version:
type: string
description: Service version
example: "0.1.0-dev"
components:
type: object
properties:
database:
type: string
enum: [up, down]
example: "up"
mta:
type: string
enum: [up, down]
example: "up"
uptime:
type: integer
description: Service uptime in seconds
example: 3600
Error:
type: object
required:
- error
- message
properties:
error:
type: string
description: Error code
example: "not_found"
message:
type: string
description: Human-readable error message
example: "Test not found"
details:
type: string
description: Additional error details