openapi: 3.1.0
info:
  title: CreatorNode Visual API — Render Chem
  description: >
    Render SMILES chemical notation strings as 2D molecular structure diagrams.


    Outputs base64 SVG (UTF-8) or base64 PNG.

    Supports optional atom highlighting (SMILES atom class) and per-atom weights
    heatmap overlays.
  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/visual
    description: Production
tags:
  - name: Chemistry
    description: Chemistry rendering endpoints
paths:
  /v1/render-chem:
    post:
      operationId: renderChem
      tags:
        - Chemistry
      summary: Render a SMILES string as a 2D molecular structure diagram
      description: >
        Converts a SMILES chemical notation string into a 2D structural formula
        image.

        Defaults to `responseFormat=json`; use `responseFormat=file` for raw SVG
        or PNG output.
      security:
        - ApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RenderChemRequest"
            examples:
              highlight-and-weights:
                summary: Highlight atoms and draw weights heatmap
                value:
                  responseFormat: json
                  smiles: "[CH3:1][CH2:2][OH:3]"
                  format: svg
                  theme: light
                  preset: publication
                  options:
                    width: 600
                    height: 400
                    highlightAtoms:
                      - atomClass: 2
                        color: "#ff0000"
                    weights:
                      values:
                        - 0
                        - 0.5
                        - 1
                      normalized: true
      responses:
        "200":
          description: Rendered molecular structure (`json` by default, or raw SVG/PNG
            when `responseFormat=file`)
          headers:
            X-Processing-Time-Ms:
              description: Processing time in milliseconds
              schema:
                type: integer
            X-Cache-Hit:
              description: Whether result was from cache
              schema:
                type: boolean
            X-Credits-Used:
              description: Credits consumed by this request (present only for paid tiers)
              schema:
                type: integer
                example: 3
            X-Credits-Remaining:
              description: Remaining credits on the API key (present only for paid tiers with
                prepaid credits)
              schema:
                type: integer
            X-Content-Type-Options:
              description: Security header
              schema:
                type: string
                enum:
                  - nosniff
            X-Molecular-Formula:
              description: Molecular formula when available
              schema:
                type: string
            X-Image-Width:
              description: Output image width in pixels
              schema:
                type: integer
            X-Image-Height:
              description: Output image height in pixels
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RenderChemResponse"
            image/svg+xml:
              schema:
                type: string
                format: binary
            image/png:
              schema:
                type: string
                format: binary
        "400":
          description: Invalid SMILES or 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: Visual rendering service is temporarily saturated. Retry shortly.
                meta:
                  requestId: abc123
components:
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: APIM subscription key for authentication. Free tier available
        without key.
  schemas:
    RenderChemColors:
      type: object
      description: Custom per-element color overrides (hex format
      properties:
        C:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        O:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        N:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        S:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        F:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        CL:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        BR:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        I:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        P:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        B:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        SI:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        H:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
        BACKGROUND:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
    RenderChemOptions:
      type: object
      properties:
        width:
          type: integer
          minimum: 100
          maximum: 2048
        height:
          type: integer
          minimum: 100
          maximum: 2048
        fit:
          type: string
          enum:
            - contain
            - stretch
          description: SVG preserveAspectRatio mapping
        bondThickness:
          type: number
          minimum: 0.3
          maximum: 3
        bondLength:
          type: number
          minimum: 10
          maximum: 50
        bondSpacing:
          type: number
          minimum: 1
          maximum: 10
        atomVisualization:
          type: string
          enum:
            - default
            - balls
            - none
        terminalCarbons:
          type: boolean
        explicitHydrogens:
          type: boolean
        compactDrawing:
          type: boolean
        padding:
          type: number
          minimum: 0
          maximum: 100
        transparent:
          type: boolean
          description: Transparent background (SVG only)
        colors:
          $ref: "#/components/schemas/RenderChemColors"
        highlightAtoms:
          type: array
          description: |
            Atom highlights by SMILES atom class (e.g. [C:1]).
            Each entry highlights atoms whose `atomClass` matches.
          maxItems: 500
          items:
            type: object
            required:
              - atomClass
            properties:
              atomClass:
                type: integer
                minimum: 0
              color:
                type: string
                pattern: ^#[0-9A-Fa-f]{6}$
                description: Highlight color (#RRGGBB)
        weights:
          type: object
          description: >
            Heatmap/weights overlay.

            `values` must have the same length as the number of heavy atoms in
            the molecule.
          required:
            - values
          properties:
            values:
              type: array
              minItems: 1
              maxItems: 5000
              items:
                type: number
            normalized:
              type: boolean
              description: If true, weights are treated as already normalized.
    RenderChemRequest:
      type: object
      required:
        - smiles
      properties:
        responseFormat:
          type: string
          enum:
            - json
            - file
          default: json
          description: >
            Success response transport.

            - `json` (default): JSON wrapper with render metadata and optional
            recommendations.

            - `file`: raw SVG or PNG body with selected metadata in headers.
        smiles:
          type: string
          minLength: 1
          maxLength: 5000
          description: SMILES chemical notation string
          example: CC(=O)Oc1ccccc1C(=O)O
        format:
          type: string
          enum:
            - svg
            - png
          default: svg
          description: Output format
        theme:
          type: string
          enum:
            - light
            - dark
          default: light
          description: Rendering theme preset
        preset:
          type: string
          enum:
            - default
            - publication
            - presentation
            - thumbnail
            - social-card
          description: Quality/size preset (overrides some options)
        options:
          $ref: "#/components/schemas/RenderChemOptions"
    RenderChemResponseMeta:
      type: object
      required:
        - requestId
        - format
        - contentType
        - processingTimeMs
        - sizeBytes
        - cached
        - molecularFormula
        - width
        - height
      properties:
        requestId:
          type: string
          description: Unique request identifier
        format:
          type: string
          enum:
            - svg
            - png
          description: Artifact format selected by the request.
        contentType:
          type: string
          description: MIME type for the produced artifact.
        filename:
          type: string
          description: Suggested filename for file-mode consumers.
        processingTimeMs:
          type: integer
          description: Processing time in milliseconds
        sizeBytes:
          type: integer
          description: Size in bytes (base64 length)
        cached:
          type: boolean
          description: Whether result was served from cache
        molecularFormula:
          type: string
          description: Molecular formula when available
          example: C9H8O4
        width:
          type: integer
          description: Output width in pixels
        height:
          type: integer
          description: Output height in pixels
    RenderChemResponse:
      type: object
      required:
        - success
        - data
        - meta
      properties:
        success:
          type: boolean
          enum:
            - true
        data:
          type: string
          description: Base64-encoded output (SVG UTF-8 or PNG)
        meta:
          $ref: "#/components/schemas/RenderChemResponseMeta"
        recommendations:
          type: array
          items:
            $ref: "#/components/schemas/Recommendation"
          description: Contextual recommendations (max 2)
    Recommendation:
      type: object
      required:
        - type
        - title
        - message
        - priority
      properties:
        type:
          type: string
          enum:
            - upgrade
            - tip
            - warning
        title:
          type: string
        message:
          type: string
        priority:
          type: string
          enum:
            - high
            - medium
            - low
        url:
          type: string
          format: uri
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          const: false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code. See each endpoint for possible values.
            message:
              type: string
            details:
              type: object
              description: Additional context about the error (varies by endpoint).
              additionalProperties: true
        meta:
          type: object
          required:
            - requestId
          properties:
            requestId:
              type: string
            demoMode:
              type: boolean
              description: Whether this is a demo endpoint response
        recommendations:
          type: array
          items:
            $ref: "#/components/schemas/Recommendation"
    RenderChemDemoRequest:
      type: object
      required:
        - smiles
      properties:
        smiles:
          type: string
          minLength: 1
          description: |
            SMILES string. The demo endpoint returns pre-built sample output —
            it does not render your exact SMILES.
          example: CC(=O)Oc1ccccc1C(=O)O
        format:
          type: string
          enum:
            - svg
            - png
          default: svg
    RenderChemDemoResponse:
      allOf:
        - $ref: "#/components/schemas/RenderChemResponse"
        - type: object
          required:
            - demoMode
            - warning
          properties:
            demoMode:
              type: boolean
              enum:
                - true
              description: Always `true` — indicates this is demo data
            warning:
              type: string
              description: Human-readable notice that this is pre-built demo output
