openapi: 3.1.0
info:
  title: CreatorNode Science API — Chemistry Validate
  description: |
    Validate a chemical notation string (SMILES, InChI, Molfile) and return
    canonical representations and molecular metadata.
  version: 1.0.0
  contact:
    name: CreatorNode Support
    url: https://creatornode.io/support
  license:
    name: Proprietary
    url: https://creatornode.io/legal
servers:
  - url: https://api.creatornode.io/science
    description: Production
tags:
  - name: Chemistry
    description: Chemistry endpoints
paths:
  /v1/chemistry/validate:
    post:
      operationId: validateChemistry
      tags:
        - Chemistry
      summary: Validate a chemical notation string and return molecular metadata
      description: >
        Accepts SMILES, InChI, or MDL Molfile input, validates using RDKit,

        and returns canonical representations with molecular descriptors.


        Note: Invalid molecule input returns HTTP 200 with `success: true` and
        `data.valid: false`.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ValidateChemistryRequest"
      responses:
        "200":
          description: Validation result (check data.valid for validity)
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ValidateChemistryValidResponse"
                  - $ref: "#/components/schemas/ValidateChemistryInvalidResponse"
        "400":
          description: Request-level validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Unauthorized
        "429":
          description: Rate limited
        "503":
          description: Service temporarily saturated
          headers:
            Retry-After:
              description: Seconds before retrying the request
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                success: false
                error:
                  code: SERVICE_BUSY
                  message: Chemistry service is temporarily saturated. Retry shortly.
                meta:
                  requestId: abc123
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: APIM subscription key for authenticated access. Without a key,
        requests use free tier limits.
  schemas:
    Recommendation:
      type: object
      required:
        - type
        - title
        - message
      properties:
        type:
          type: string
          enum:
            - upgrade
            - top_up
            - feature
            - tip
            - warning
            - fix
        title:
          type: string
        message:
          type: string
        action:
          type: object
          required:
            - label
            - url
          properties:
            label:
              type: string
            url:
              type: string
              format: uri
        priority:
          type: string
          enum:
            - low
            - medium
            - high
          default: low
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Error code (e.g. VALIDATION_ERROR, INPUT_TOO_LARGE,
                PROCESSING_TIMEOUT)
            message:
              type: string
            details:
              type: object
              additionalProperties: true
        meta:
          type: object
          properties:
            requestId:
              type: string
        recommendations:
          type: array
          items:
            $ref: "#/components/schemas/Recommendation"
    ValidateChemistryOptions:
      type: object
      description: Output control and processing options.
      properties:
        canonicalSmiles:
          type: boolean
          default: true
        inchi:
          type: boolean
          default: true
        inchiKey:
          type: boolean
          default: false
          description: Optional output availability depends on the current plan and
            configuration.
        molblock:
          type: boolean
          default: false
          description: Optional output availability depends on the current plan and
            configuration.
        descriptors:
          type: boolean
          default: true
        sanitize:
          type: boolean
          default: true
    ValidateChemistryRequest:
      type: object
      required:
        - input
      properties:
        input:
          type: string
          minLength: 1
          maxLength: 50000
          description: Chemical notation to validate (SMILES, InChI, or MDL
            Molfile/Molblock).
          example: CC(=O)OC1=CC=CC=C1C(=O)O
        format:
          type: string
          enum:
            - auto
            - smiles
            - inchi
            - mol
          default: auto
          description: Optional format hint. `auto` uses heuristic detection.
        options:
          $ref: "#/components/schemas/ValidateChemistryOptions"
    ValidateChemistryMeta:
      type: object
      required:
        - requestId
        - processingTimeMs
        - rdkitVersion
        - cached
      properties:
        requestId:
          type: string
        processingTimeMs:
          type: integer
          minimum: 0
        rdkitVersion:
          type: string
          example: 2025.3.4
        cached:
          type: boolean
    MoleculeMetadata:
      type: object
      properties:
        molecularFormula:
          type: string
        exactMolecularWeight:
          type: number
        numAtoms:
          type: integer
        numBonds:
          type: integer
        numRings:
          type: integer
        numHeavyAtoms:
          type: integer
        numHBA:
          type: integer
        numHBD:
          type: integer
        TPSA:
          type: number
        cLogP:
          type: number
        numRotatableBonds:
          type: integer
        numAromaticRings:
          type: integer
        hasStereo:
          type: boolean
    DrugLikenessRule:
      type: object
      required:
        - rule
        - passed
        - value
      properties:
        rule:
          type: string
          example: MW ≤ 500
        passed:
          type: boolean
        value:
          type: number
    DrugLikeness:
      type: object
      required:
        - lipinskiRo5
        - violations
        - rules
      properties:
        lipinskiRo5:
          type: boolean
        violations:
          type: integer
          minimum: 0
          maximum: 4
        rules:
          type: array
          minItems: 4
          maxItems: 4
          items:
            $ref: "#/components/schemas/DrugLikenessRule"
    ValidateChemistryValidData:
      type: object
      required:
        - valid
        - format
        - input
      properties:
        valid:
          type: boolean
          enum:
            - true
        format:
          type: string
          enum:
            - smiles
            - inchi
            - mol
        input:
          type: string
          description: Normalized input used for processing.
        canonicalSmiles:
          type: string
        inchi:
          type: string
        inchiKey:
          type: string
        molblock:
          type: string
        metadata:
          $ref: "#/components/schemas/MoleculeMetadata"
        drugLikeness:
          $ref: "#/components/schemas/DrugLikeness"
    ValidateChemistryInvalidData:
      type: object
      required:
        - valid
        - format
        - input
        - error
      properties:
        valid:
          type: boolean
          enum:
            - false
        format:
          type: string
          enum:
            - smiles
            - inchi
            - mol
            - unknown
        input:
          type: string
        error:
          type: object
          required:
            - message
          properties:
            message:
              type: string
            details:
              type: string
    ValidateChemistryValidResponse:
      type: object
      required:
        - success
        - data
        - meta
      properties:
        success:
          type: boolean
          enum:
            - true
        data:
          $ref: "#/components/schemas/ValidateChemistryValidData"
        meta:
          $ref: "#/components/schemas/ValidateChemistryMeta"
        recommendations:
          type: array
          items:
            $ref: "#/components/schemas/Recommendation"
    ValidateChemistryInvalidResponse:
      type: object
      required:
        - success
        - data
        - meta
      properties:
        success:
          type: boolean
          enum:
            - true
        data:
          $ref: "#/components/schemas/ValidateChemistryInvalidData"
        meta:
          $ref: "#/components/schemas/ValidateChemistryMeta"
        recommendations:
          type: array
          items:
            $ref: "#/components/schemas/Recommendation"
    ValidateChemistryDemoRequest:
      type: object
      description: Demo endpoint accepts the same shape as the full endpoint but
        ignores input and returns a deterministic sample response.
      properties:
        input:
          type: string
          minLength: 1
          maxLength: 50000
          description: Chemical notation (ignored by demo — any value accepted).
          example: CC(=O)OC1=CC=CC=C1C(=O)O
        format:
          type: string
          enum:
            - auto
            - smiles
            - inchi
            - mol
          default: auto
        options:
          $ref: "#/components/schemas/ValidateChemistryOptions"
    ValidateChemistryDemoResponse:
      $ref: "#/components/schemas/ValidateChemistryValidResponse"
