openapi: 3.1.0
info:
  title: CreatorNode Visual API — Render Timeline
  description: |
    Render event timelines as SVG or PNG infographics using Satori.

    Vertical or horizontal orientation with plan-dependent event limits.
    Perfect for project milestones, changelogs, and roadmap visuals.
  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: Timeline
    description: Timeline infographic rendering endpoints
paths:
  /v1/render-timeline:
    post:
      operationId: renderTimeline
      tags:
        - Timeline
      summary: Render a timeline infographic
      description: Render an array of events as a timeline infographic to SVG or PNG.
        Supports vertical/horizontal orientations, alternate/compact layouts,
        light/dark themes, custom accent colours, and auto-sizing. 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/RenderTimelineRequest"
            examples:
              minimal:
                summary: Minimal request (auto-sized)
                value:
                  responseFormat: json
                  events:
                    - date: 2026-01-15
                      title: Project Kickoff
                    - date: 2026-02-01
                      title: MVP Shipped
                      text: First public release
              withTitle:
                summary: Timeline with a title
                value:
                  title: Project Roadmap 2026
                  events:
                    - date: Q1 2026
                      title: Research
                    - date: Q2 2026
                      title: Build
                    - date: Q3 2026
                      title: Launch
              horizontal:
                summary: Horizontal layout (auto-width)
                value:
                  events:
                    - date: Q1 2026
                      title: Research
                    - date: Q2 2026
                      title: Build
                    - date: Q3 2026
                      title: Launch
                  orientation: horizontal
              darkTheme:
                summary: Dark theme
                value:
                  events:
                    - date: 2026-01-15
                      title: Project Kickoff
                    - date: 2026-02-01
                      title: MVP Shipped
                  theme: dark
              customAccent:
                summary: Custom accent colour
                value:
                  events:
                    - date: Jan
                      title: Idea
                    - date: Feb
                      title: Prototype
                    - date: Mar
                      title: Launch
                  accentColor: "#10b981"
              darkAccent:
                summary: Dark theme with custom accent
                value:
                  events:
                    - date: Sprint 1
                      title: Setup
                    - date: Sprint 2
                      title: Build
                    - date: Sprint 3
                      title: Ship
                  theme: dark
                  accentColor: "#f59e0b"
              manyEvents:
                summary: Auto-height for many events
                value:
                  events:
                    - date: Jan
                      title: Idea
                    - date: Feb
                      title: Prototype
                    - date: Mar
                      title: MVP
                    - date: Apr
                      title: Beta
                    - date: May
                      title: Launch
                    - date: Jun
                      title: Scale
                    - date: Jul
                      title: Expand
                    - date: Aug
                      title: IPO
              pngOutput:
                summary: PNG output (OG size)
                value:
                  responseFormat: file
                  events:
                    - date: Jan 2026
                      title: Idea
                    - date: Feb 2026
                      title: Prototype
                    - date: Mar 2026
                      title: Launch
                  format: png
                  width: 1200
                  height: 630
              compactVertical:
                summary: Compact layout (narrow / sidebar)
                value:
                  events:
                    - date: Jan
                      title: Idea
                    - date: Feb
                      title: Prototype
                    - date: Mar
                      title: MVP
                    - date: Apr
                      title: Launch
                  layout: compact
                  width: 400
              compactHorizontal:
                summary: Compact horizontal
                value:
                  events:
                    - date: Q1
                      title: Plan
                    - date: Q2
                      title: Build
                    - date: Q3
                      title: Ship
                  orientation: horizontal
                  layout: compact
                  height: 280
              transparentBg:
                summary: Transparent background (SVG)
                value:
                  events:
                    - date: Jan
                      title: Idea
                    - date: Feb
                      title: Prototype
                    - date: Mar
                      title: Launch
                  transparent: true
              monoFont:
                summary: Monospace font (developer timeline)
                value:
                  events:
                    - date: v1.0
                      title: Initial Release
                    - date: v1.1
                      title: Bug Fixes
                    - date: v2.0
                      title: Major Rewrite
                  fontFamily: mono
                  theme: dark
      responses:
        "200":
          description: Successful render (`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: 2
            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
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RenderTimelineResponse"
              example:
                success: true
                data: <svg width='800' height='630' viewBox='0 0 800 630'
                  xmlns='http://www.w3.org/2000/svg'>...</svg>
                meta:
                  requestId: req_abc123
                  format: svg
                  contentType: image/svg+xml
                  orientation: vertical
                  processingTimeMs: 120
                  eventCount: 3
                  sizeBytes: 4200
                  width: 800
                  height: 630
            image/svg+xml:
              schema:
                type: string
                format: binary
            image/png:
              schema:
                type: string
                format: binary
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                noEvents:
                  summary: No events provided
                  value:
                    success: false
                    error:
                      code: VALIDATION_ERROR
                      message: At least one event is required
                    meta:
                      requestId: abc123
                tooManyEvents:
                  summary: Too many events
                  value:
                    success: false
                    error:
                      code: TOO_MANY_EVENTS
                      message: Too many events for the current configuration.
                    meta:
                      requestId: abc123
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          description: Rate limited
          headers:
            Retry-After:
              description: Seconds until rate limit resets
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "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:
    RenderTimelineRequest:
      type: object
      required:
        - events
      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.
        events:
          type: array
          items:
            $ref: "#/components/schemas/TimelineEvent"
          minItems: 1
          maxItems: 50
          description: >
            Events to display on the timeline.

            Rendered in array order — the API does **not** sort them.

            Callers are responsible for sending events in the desired display
            order.
        width:
          type: integer
          minimum: 200
          maximum: 4096
          description: >
            Image width in pixels. Omit for auto-sizing.

            Vertical default: 800. Horizontal: grows with event count (~220
            px/event).
        height:
          type: integer
          minimum: 200
          maximum: 4096
          description: >
            Image height in pixels. Omit for auto-sizing.

            Vertical: grows with event count (~90 px/event). Horizontal default:
            400.
        orientation:
          type: string
          enum:
            - vertical
            - horizontal
          default: vertical
          description: Layout orientation
        format:
          type: string
          enum:
            - svg
            - png
          default: svg
          description: Output format
        layout:
          type: string
          enum:
            - alternate
            - compact
          default: alternate
          description: >
            Card layout mode.

            - `alternate` (default) — cards zigzag left/right (vertical) or
            top/bottom (horizontal)

            - `compact` — all cards on one side, ideal for narrow containers or
            embedding
        title:
          type: string
          maxLength: 200
          description: Optional title displayed above the timeline
          example: Project Roadmap 2026
        theme:
          type: string
          enum:
            - light
            - dark
          default: light
          description: |
            Theme preset for the timeline.
            - `light` — White background, dark text, blue accents
            - `dark` — Dark slate background, light text, blue accents
        accentColor:
          type: string
          pattern: ^#[0-9A-Fa-f]{6}$
          description: |
            Custom accent colour (#RRGGBB). Overrides the dot and date
            colours in any theme preset.
          example: "#10b981"
        transparent:
          type: boolean
          default: false
          description: |
            Transparent background (SVG only).
            When `true`, the timeline has no background fill — useful for
            embedding into pages with a custom background colour.
        fontFamily:
          type: string
          enum:
            - inter
            - roboto
            - mono
          default: inter
          description: |
            Font family for the timeline.
            - `inter` — clean sans-serif (default)
            - `roboto` — geometric sans-serif (Material Design)
            - `mono` — JetBrains Mono (monospace, ideal for dev/tech timelines)
    TimelineEvent:
      type: object
      required:
        - date
        - title
      properties:
        date:
          type: string
          minLength: 1
          maxLength: 100
          description: Display date (free-form, e.g. "2026-02-01" or "Q1 2026")
          example: 2026-02-01
        title:
          type: string
          minLength: 1
          maxLength: 200
          description: Short title for the event
          example: MVP Shipped
        text:
          type: string
          maxLength: 500
          description: Optional longer description
          example: First public release
    RenderTimelineResponse:
      type: object
      required:
        - success
        - data
        - meta
      properties:
        success:
          type: boolean
          enum:
            - true
        data:
          type: string
          description: |
            Rendered output:
            - SVG: Raw SVG string
            - PNG: Base64 encoded image
        meta:
          $ref: "#/components/schemas/TimelineResponseMeta"
        recommendations:
          type: array
          items:
            $ref: "#/components/schemas/Recommendation"
          description: Contextual recommendations (max 2)
    TimelineResponseMeta:
      type: object
      required:
        - requestId
        - format
        - contentType
        - orientation
        - processingTimeMs
        - eventCount
        - sizeBytes
        - 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.
        orientation:
          type: string
          enum:
            - vertical
            - horizontal
        processingTimeMs:
          type: integer
          description: Processing time in milliseconds
        eventCount:
          type: integer
          description: Number of events rendered
        sizeBytes:
          type: integer
          description: Output size in bytes
        width:
          type: integer
          description: Image width in pixels
        height:
          type: integer
          description: Image height in pixels
        cached:
          type: boolean
          description: Whether the result was served from cache
    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"
    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
    RenderTimelineDemoRequest:
      type: object
      required:
        - events
      properties:
        events:
          type: array
          items:
            $ref: "#/components/schemas/TimelineEvent"
          minItems: 1
          description: |
            Events array. The demo endpoint returns a pre-built sample
            regardless of the events you provide.
        width:
          type: integer
          default: 800
        height:
          type: integer
          default: 630
        orientation:
          type: string
          enum:
            - vertical
            - horizontal
          default: vertical
        format:
          type: string
          enum:
            - svg
            - png
          default: svg
    RenderTimelineDemoResponse:
      allOf:
        - $ref: "#/components/schemas/RenderTimelineResponse"
        - 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
