openapi: 3.0.3
info:
  title: ScoreSender REST API
  description: >
    ScoreSender provides automated domain email authentication diagnostics (SPF, DKIM, DMARC), 8-DNSBL blocklist monitoring, and Google Postmaster Tools integration.
  version: 1.0.0
  contact:
    name: ScoreSender Developer Support
    email: api@scoresender.com
    url: https://scoresender.com/docs
servers:
  - url: https://api.scoresender.com/api/v1
    description: Production API Server
  - url: http://localhost:3000/api/v1
    description: Local Sandbox Server

security:
  - ApiKeyAuth: []

paths:
  /health:
    get:
      summary: Instant Domain Health & Reputation Check
      description: Evaluates live SPF, DKIM, DMARC, 8 DNSBL blocklists, and Google Postmaster signals for any FQDN domain.
      operationId: getDomainHealth
      parameters:
        - name: domain
          in: query
          required: true
          description: Domain name to evaluate (e.g. example.com)
          schema:
            type: string
            example: example.com
      responses:
        '200':
          description: Live domain health evaluation report
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
        '400':
          $ref: '#/components/responses/InvalidDomainError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/RateLimitError'

  /domains/{id}/history:
    get:
      summary: Get Domain Historical Reputation Snapshots
      description: Returns time-series history records for chart rendering and trend analysis.
      operationId: getDomainHistory
      parameters:
        - name: id
          in: path
          required: true
          description: Unique Domain ID or domain name
          schema:
            type: string
            example: 11111111-1111-1111-1111-111111111111
        - name: days
          in: query
          required: false
          description: Number of historical days to return (1-365, default 30)
          schema:
            type: integer
            default: 30
            example: 30
      responses:
        '200':
          description: Time series history snapshots
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HistoryResponse'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/RateLimitError'

  /domains:
    post:
      summary: Register New Domain for Automated Monitoring
      description: Adds a domain to active monitoring list for scheduled Postgres Cron snapshots.
      operationId: createDomain
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - domain_name
              properties:
                domain_name:
                  type: string
                  example: acme-corp.io
      responses:
        '201':
          description: Domain successfully registered
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateDomainResponse'
        '400':
          $ref: '#/components/responses/InvalidDomainError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/RateLimitError'

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: Enter your ScoreSender API Key (e.g. sk_live_...)

  schemas:
    HealthResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        domain:
          type: string
          example: example.com
        overall_score:
          type: integer
          example: 100
        breakdown:
          type: object
          properties:
            spf_score:
              type: integer
              example: 100
            dkim_score:
              type: integer
              example: 100
            dmarc_score:
              type: integer
              example: 100
            blocklist_score:
              type: integer
              example: 100
            postmaster_score:
              type: integer
              nullable: true
              example: 100
        scoring_weights:
          type: object
          properties:
            spf:
              type: integer
              example: 25
            dkim:
              type: integer
              example: 25
            dmarc:
              type: integer
              example: 25
            blocklist:
              type: integer
              example: 25
            postmaster:
              type: integer
              example: 0
        blocklist_hits:
          type: array
          items:
            type: string
          example: []
        postmaster_connected:
          type: boolean
          example: false
        evaluated_at:
          type: string
          format: date-time
          example: '2026-08-07T12:00:00.000Z'

    HistoryResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        domain_id:
          type: string
          example: 11111111-1111-1111-1111-111111111111
        days:
          type: integer
          example: 30
        summary:
          type: object
          properties:
            current_score:
              type: integer
              example: 100
            average_score:
              type: integer
              example: 98
            total_snapshots:
              type: integer
              example: 30
        history:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              checked_at:
                type: string
                format: date-time
              overall_score:
                type: integer
              spf_score:
                type: integer
              dkim_score:
                type: integer
              dmarc_score:
                type: integer
              blocklist_score:
                type: integer

    CreateDomainResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
          example: Domain registered successfully.
        domain:
          type: object
          properties:
            id:
              type: string
            domain_name:
              type: string
            is_active:
              type: boolean
            initial_health_score:
              type: integer

    ErrorPayload:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              example: INVALID_DOMAIN
            message:
              type: string
              example: Invalid domain parameter provided.
            details:
              type: object
              nullable: true

  responses:
    InvalidDomainError:
      description: Invalid domain name or missing parameter
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorPayload'
    UnauthorizedError:
      description: Invalid or missing API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorPayload'
    RateLimitError:
      description: API Rate Limit Exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorPayload'
