openapi: 3.1.0
info:
  title: Obsidex API
  description: |
    Neural handwriting synthesis at scale. Generate authentic human-grade digital ink via REST API.
    
    ## Authentication
    All API requests require a Bearer Token in the `Authorization` header.
    
    ```
    Authorization: Bearer obx_live_xxxxx
    ```
    
    Generate keys in your dashboard under the API section.
    
    ## Token Model
    - 1 character = 1 token (Base cost)
    - Spaces count
    - PNG export: 1.5x multiplier
    - PDF export: 1.2x multiplier
    
    ## Rate Limits
    - Basic: 5 renders/month (API Disabled)
    - Pro: 50,000 renders/month
    - Enterprise: 250,000 renders/month
  version: 1.0.0
  contact:
    email: api@obsidexsolutions.com
  license:
    name: Proprietary
    url: https://obsidex.ai/terms

servers:
  - url: https://api.obsidex.ai
    description: Production
  - url: https://api-staging.obsidex.ai
    description: Staging

components:
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: "Enter your API key (format: `obx_live_...`)"

  schemas:
    RenderRequest:
      type: object
      required:
        - text
        - style
      properties:
        text:
          type: string
          description: The text to render as handwriting
          example: "Approved · Signed · Verified"
          maxLength: 5000
        style:
          type: string
          description: |
            Handwriting style name. 
            Engines: `FLOW` (Natural), `ARCHITECT` (Precise), `VELOCITY` (Speed).
            Or one of 35 fonts (e.g., `IndieFlower`, `Caveat`, `PermanentMarker`).
          example: "FLOW"
        format:
          type: string
          enum: [svg, png, pdf]
          default: svg
          description: Output format
        ink:
          type: string
          enum: [black, blue, crimson, green]
          default: black
          description: Handwriting ink color
        previewMode:
          type: boolean
          default: false
          description: Fast rendering mode for previews (no jitter)
        options:
          type: object
          properties:
            width:
              type: integer
              default: 600
            height:
              type: integer
              default: 200
            fontSize:
              type: integer
              default: 48
            variance:
              type: number
              default: 0.12
              description: Amount of natural stroke variation (0.0 to 1.0)
            pressure:
              type: boolean
              default: true
            seed:
              type: integer
              description: Deterministic seed for variation

    RenderResponse:
      type: object
      properties:
        render_id:
          type: string
          example: "rnd_abc123de"
        style:
          type: string
          example: "flow"
        ink:
          type: string
          example: "black"
        format:
          type: string
          example: "svg"
        content_type:
          type: string
          example: "image/svg+xml"
        usage:
          type: object
          properties:
            tokens_used:
              type: integer
            tokens_remaining:
              type: integer
        output:
          type: string
          description: The rendered output (UTF-8 for SVG, Base64 for PNG/PDF)
        output_encoding:
          type: string
          enum: [utf-8, base64]
        output_url:
          type: string
          format: uri
        expires_at:
          type: string
          format: date-time

    Error:
      type: object
      properties:
        error:
          type: string

security:
  - ApiKeyAuth: []

paths:
  /v1/render:
    post:
      summary: Render handwriting
      description: Synthesize text into neural handwriting strokes
      operationId: renderHandwriting
      tags:
        - Render
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenderRequest'
      responses:
        '200':
          description: Successful render
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RenderResponse'
        '400':
          description: Invalid request
        '401':
          description: Unauthorized
        '429':
          description: Quota exceeded or rate limited

  /v1/usage:
    get:
      summary: Get usage
      description: Retrieve current quota metrics for your API key
      operationId: getUsage
      tags:
        - Usage
      responses:
        '200':
          description: Usage metrics
          content:
            application/json:
              schema:
                type: object
                properties:
                  tokens_limit:
                    type: integer
                  tokens_used:
                    type: integer
                  tokens_remaining:
                    type: integer
                  plan:
                    type: string
