openapi: 3.0.3
info:
  title: Ipasis GeoAPI
  description: Real-time IP Intelligence & Reputation API for fraud prevention.
  version: 1.0.0
  contact:
    url: https://ipasis.com

servers:
  - url: https://api.ipasis.com
    description: Production

security:
  - BearerAuth: []
  - ApiKeyHeader: []
  - ApiKeyQuery: []

paths:
  /healthz:
    get:
      summary: Health check
      security: []
      responses:
        "200":
          description: Service healthy
          content:
            text/plain:
              schema:
                type: string
                example: ok
        "503":
          description: Service unhealthy (MMDB not loaded)

  /v1/lookup:
    get:
      summary: IP lookup
      description: |
        Returns geolocation, ASN, privacy flags (VPN/proxy/Tor/hosting),
        abuse contacts, and company info for the given IP address.
        This is the primary hot-path endpoint — sub-20ms p99 target.
      parameters:
        - name: ip
          in: query
          required: true
          schema:
            type: string
          example: "8.8.8.8"
        - name: details
          in: query
          required: false
          schema:
            type: string
            enum: ["true", "false"]
          description: Include raw provider/feed details
      responses:
        "200":
          description: IP lookup result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/IPLookupResponse"
        "400":
          description: Missing or invalid IP
        "401":
          description: Missing or invalid API key
        "429":
          description: Rate limit exceeded

  /v1/validate-email:
    get:
      summary: Validate email (GET)
      parameters:
        - name: email
          in: query
          required: true
          schema:
            type: string
          example: "user@example.com"
        - name: ip
          in: query
          required: false
          schema:
            type: string
          description: Optional IP for combined risk scoring
      responses:
        "200":
          description: Email validation result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EmailValidationResponse"
        "400":
          description: Missing email
        "401":
          description: Missing or invalid API key
    post:
      summary: Validate email (POST)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email]
              properties:
                email:
                  type: string
                ip:
                  type: string
      responses:
        "200":
          description: Email validation result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EmailValidationResponse"

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
    ApiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
    ApiKeyQuery:
      type: apiKey
      in: query
      name: key

  schemas:
    IPLookupResponse:
      type: object
      properties:
        ip:
          type: string
          example: "8.8.8.8"
        city:
          type: string
          example: "Mountain View"
        region:
          type: string
          example: "California"
        country:
          type: string
          example: "US"
        loc:
          type: string
          example: "37.386,-122.0838"
        postal:
          type: string
        timezone:
          type: string
          example: "America/Los_Angeles"
        asn:
          type: object
          properties:
            asn:
              type: string
              example: "AS15169"
            name:
              type: string
              example: "Google LLC"
            domain:
              type: string
            route:
              type: string
            type:
              type: string
              enum: [hosting, isp, education, ""]
        company:
          type: object
          properties:
            name:
              type: string
            domain:
              type: string
            type:
              type: string
        privacy:
          type: object
          properties:
            vpn:
              type: boolean
            proxy:
              type: boolean
            tor:
              type: boolean
            relay:
              type: boolean
            hosting:
              type: boolean
            abuse:
              type: boolean
            ai:
              type: boolean
            crawler:
              type: boolean
            service:
              type: string
            type:
              type: string
        abuse:
          type: object
          properties:
            address:
              type: string
            country:
              type: string
            email:
              type: string
            name:
              type: string
            network:
              type: string
            phone:
              type: string
        domains:
          type: object
          properties:
            page:
              type: integer
            total:
              type: integer
            domains:
              type: array
              items:
                type: string
        details:
          type: object
          description: Raw provider/feed details (only when details=true)

    EmailValidationResponse:
      type: object
      properties:
        request_id:
          type: string
        success:
          type: boolean
        processed_at:
          type: string
          format: date-time
        risk:
          type: object
          properties:
            score:
              type: integer
              minimum: 0
              maximum: 100
            level:
              type: string
              enum: [LOW, MEDIUM, HIGH, CRITICAL]
            recommendation:
              type: string
              enum: [ALLOW, REVIEW, BLOCK]
            primary_reasons:
              type: array
              items:
                type: string
        email:
          type: object
          properties:
            address:
              type: string
            status:
              type: string
              enum: [valid, invalid]
            deliverability:
              type: string
              enum: [deliverable, risky, undeliverable]
            type:
              type: string
              enum: [personal, disposable, role, business, unknown]
            domain_age_days:
              type: integer
              nullable: true
            checks:
              type: object
              properties:
                is_valid_syntax:
                  type: boolean
                is_disposable:
                  type: boolean
                is_gibberish:
                  type: boolean
                is_newborn_domain:
                  type: boolean
                is_catch_all:
                  type: boolean
                  nullable: true
                is_role_account:
                  type: boolean
                mx_records_found:
                  type: boolean
                  nullable: true
                smtp_connect:
                  type: boolean
                  nullable: true
        ip:
          $ref: "#/components/schemas/IPLookupResponse"
          nullable: true
