API Documentation Generator
Run ID: 69cbf42761b1021a29a8de6a2026-03-31Development
PantheraHive BOS
BOS Dashboard

Step 1: Architecture Plan for API Documentation Generator

This document outlines the proposed architecture for the API Documentation Generator. The goal is to create a robust, flexible, and extensible system capable of generating high-quality, professional API documentation from various sources.


1. Overall System Goal

The primary goal of the API Documentation Generator is to automate the creation of comprehensive, interactive, and visually appealing API documentation. This includes detailed endpoint descriptions, request/response examples, authentication guidance, and SDK usage examples, ensuring developers can easily understand and integrate with the API.

2. Core Architectural Principles

To achieve our goal, the architecture will adhere to the following principles:

3. High-Level Architecture Overview

The system will broadly consist of three main stages: Input & Parsing, Core Processing & Transformation, and Output Generation.

mermaid • 1,434 chars
graph TD
    A[API Definition Sources] --> B{Input & Parsing Layer};
    B --> C[Core Processing & Transformation Engine];
    C --> D{Output Generation Layer};
    D --> E[Generated Documentation];

    subgraph API Definition Sources
        A1[OpenAPI/Swagger Spec (YAML/JSON)]
        A2[Code Annotations (e.g., JSDoc, PHPDoc, Python Docstrings)]
        A3[Custom DSL/Configuration Files]
    end

    subgraph Input & Parsing Layer
        B1[Source Readers]
        B2[Parsers & Validators]
        B3[Intermediate Data Model (IDM) Builder]
    end

    subgraph Core Processing & Transformation Engine
        C1[IDM Validator & Enricher]
        C2[Content Renderer (Templating Engine)]
        C3[Example Generator (Request/Response)]
        C4[Authentication Guide Builder]
        C5[SDK Usage Example Formatter]
        C6[Versioning & Customization Logic]
    end

    subgraph Output Generation Layer
        D1[Output Formatters (HTML, Markdown, PDF)]
        D2[Static Site Generator Integration]
        D3[Search Indexer]
        D4[Asset Management (CSS, JS, Images)]
    end

    subgraph Generated Documentation
        E1[Interactive Web Documentation]
        E2[Static Markdown Files]
        E3[PDF/Printable Guides]
        E4[Postman Collection/SDK Stubs]
    end

    F[Configuration & Theming] -- Controls --> C;
    G[CLI / Web UI] -- Triggers & Configures --> B;
    G -- Triggers & Configures --> D;
Sandboxed live preview

4. Key Architectural Components

4.1. Input & Parsing Layer

This layer is responsible for ingesting API definitions from various sources and transforming them into a standardized, internal data model.

  • 4.1.1. Source Readers:

* Purpose: Abstract away the specifics of reading data from different sources (file system, URL, database).

* Components:

* File System Reader: Reads YAML/JSON files locally.

* URL Reader: Fetches specifications from remote URLs.

* Code Scanner: Analyzes source code directories for specific annotations.

  • 4.1.2. Parsers & Validators:

* Purpose: Parse raw input into structured data and validate its schema.

* Components:

* OpenAPI/Swagger Parser: Parses YAML/JSON OpenAPI specifications (e.g., using swagger-parser or openapi-parser libraries). Includes schema validation against the OpenAPI specification.

* Annotation Parser: Extracts API metadata from code comments (e.g., JSDoc, PHPDoc, Sphinx/Napoleon for Python).

* Custom DSL Parser: For any proprietary definition language, if applicable.

  • 4.1.3. Intermediate Data Model (IDM) Builder:

* Purpose: Consolidate parsed data into a unified, language-agnostic data structure that represents all necessary API documentation elements. This IDM will be the single source of truth for the generation process.

* Structure: Define a comprehensive schema covering:

* Global API Info (title, version, description, license)

* Servers/Environments

* Endpoints (path, method, summary, description, tags)

* Parameters (name, in, type, required, schema, example)

* Request Bodies (content types, schemas, examples)

* Responses (status code, description, content types, schemas, examples)

* Security Schemes (types, flows, scopes)

* Components (schemas, headers, security schemes, examples, links, callbacks)

* Tags/Groups

* External Documentation links

4.2. Core Processing & Transformation Engine

This is the brain of the generator, responsible for enriching the IDM, generating missing content, and preparing data for rendering.

  • 4.2.1. IDM Validator & Enricher:

* Purpose: Perform semantic validation on the IDM (e.g., ensure referenced schemas exist, check for consistent naming) and enrich it with derived information (e.g., infer data types, resolve $ref pointers).

  • 4.2.2. Content Renderer (Templating Engine):

* Purpose: Utilize a flexible templating engine to map the IDM to human-readable documentation structure.

* Technology: Jinja2 (Python), Handlebars (Node.js), or similar.

* Features: Support for custom themes, partials, and conditional rendering.

  • 4.2.3. Example Generator:

* Purpose: Automatically generate realistic request and response examples based on defined schemas (JSON Schema, OpenAPI components).

* Features:

* Support for various content types (JSON, XML, form data).

* Ability to use provided example fields or generate intelligently from type, format, enum, pattern, minLength, maxLength, etc.

* Option to include multiple examples per schema/response.

  • 4.2.4. Authentication Guide Builder:

* Purpose: Generate detailed instructions for different authentication methods (API Key, OAuth2, Bearer Token, Basic Auth) based on the securitySchemes defined in the IDM.

* Content: Code snippets for common languages, step-by-step guides.

  • 4.2.5. SDK Usage Example Formatter:

* Purpose: Generate illustrative code snippets demonstrating how to interact with API endpoints using various SDKs or common HTTP client libraries.

* Mechanism: Could involve a small, internal code generation module or predefined templates for common languages (Python requests, Node.js axios, cURL).

  • 4.2.6. Versioning & Customization Logic:

* Purpose: Manage multiple API versions and apply user-defined customizations (theming, content injection).

* Features: Support for version selection, custom header/footer content, brand assets.

4.3. Output Generation Layer

This layer takes the processed and rendered content and transforms it into the desired final documentation formats.

  • 4.3.1. Output Formatters:

* Purpose: Convert the rendered content (e.g., Markdown) into specific output formats.

* Components:

* HTML Formatter: Generates static HTML files, often integrating with a static site generator.

* Markdown Formatter: Produces raw Markdown files.

* PDF Formatter: Converts HTML/Markdown to PDF (e.g., using Puppeteer, WeasyPrint, wkhtmltopdf).

* Postman Collection Exporter: Generates a Postman Collection JSON file.

  • 4.3.2. Static Site Generator Integration:

* Purpose: Leverage existing static site generators (e.g., MkDocs, Next.js, Gatsby, Hugo) for advanced features like search, navigation, and modern UI.

* Mechanism: The generator outputs content in a format consumable by the chosen SSG, which then builds the final interactive website.

  • 4.3.3. Search Indexer:

* Purpose: Generate a search index (e.g., JSON file for client-side search, or integrate with a search service) to enable efficient searching within the generated documentation.

  • 4.3.4. Asset Management:

* Purpose: Copy and manage static assets like CSS, JavaScript, images, and fonts required by the generated documentation.

4.4. User Interface / Automation

  • 4.4.1. Command-Line Interface (CLI):

* Purpose: Provide a powerful, scriptable interface for automation (e.g., CI/CD pipelines).

* Commands: generate, validate, config, init.

* Configuration: Input source paths, output directory, theme selection, versioning options.

  • 4.4.2. Web User Interface (Optional, Phase 2):

* Purpose: Offer a graphical interface for easier configuration, previewing, and triggering documentation generation.

* Features: Upload OpenAPI files, select themes, live preview, generate and download documentation.

5. Data Flow

  1. User Input: A user or CI/CD pipeline triggers the generator via CLI or Web UI, providing configuration (input source, output format, theme).
  2. Source Reading: The Input & Parsing Layer's Source Readers fetch the API definition from the specified location.
  3. Parsing & Validation: Parsers & Validators process the raw definition (e.g., OpenAPI YAML) into a structured format and validate it.
  4. IDM Creation: The IDM Builder transforms the parsed data into the standardized Intermediate Data Model.
  5. Data Enrichment: The Core Processing Engine's IDM Validator & Enricher performs semantic checks and adds derived information to the IDM.
  6. Content Generation: Content Renderer, Example Generator, Authentication Guide Builder, and SDK Usage Example Formatter use the IDM to generate documentation content (e.g., Markdown files, code snippets) based on templates and rules.
  7. Output Formatting: The Output Generation Layer's Output Formatters take the generated content and convert it into the desired final format (e.g., HTML, PDF, Postman Collection).
  8. Deployment: The final documentation (e.g., static HTML files) is stored in the specified output directory, ready for deployment to a web server or distribution.

6. Technology Stack Recommendations

  • Primary Language: Python (for its strong ecosystem in data processing, templating, and CLI tools) or Node.js (for its strong ecosystem in web development, JS-based OpenAPI tools, and CLI tools).

* Python Advantage: Libraries like PyYAML, jsonschema, Jinja2, Click (for CLI), mkdocs integration.

* Node.js Advantage: Libraries like yaml, json-schema-ref-parser, handlebars, commander (for CLI), Redocly / Swagger UI integration.

  • Templating Engine: Jinja2 (Python) or Handlebars/EJS (Node.js) for flexible content rendering.
  • OpenAPI Parsing: python-openapi-parser or PyYAML (Python); swagger-parser or yaml (Node.js).
  • Schema Validation: jsonschema (Python), ajv (Node.js).
  • Code Annotation Parsing: docstring_parser (Python), jsdoc-to-markdown (Node.js).
  • Static Site Generation (for HTML output): MkDocs (Python-based, good for technical docs), Next.js/Gatsby (React-based, highly customizable).
  • PDF Generation: WeasyPrint (Python), Puppeteer (Node.js).
  • CLI Framework: Click (Python), Commander.js or Yargs (Node.js).
  • Frontend (for optional Web UI): React, Vue, or Angular.

7. Scalability & Maintainability Considerations

  • Modularity: Strict separation of concerns will simplify updates and bug fixes.
  • Configuration: Externalize configuration (YAML, JSON files) to allow easy customization without code changes.
  • Testing: Implement unit, integration, and end-to-end tests for all components, especially parsers, transformers, and formatters.
  • Documentation: Maintain clear internal documentation for the codebase, IDM schema, and extension points.
  • Performance: For large API definitions, optimize parsing and rendering steps. Consider caching of parsed IDM.
  • Containerization: Package the generator in a Docker container for consistent environments and easy deployment.

8. Future Enhancements (Architectural Hooks)

The proposed architecture provides clear extension points for future features:

  • New Input Sources: Easily add parsers for GraphQL schemas, gRPC protobufs, etc., by implementing new Source Readers and Parsers that map to the existing IDM.
  • New Output Formats: Introduce new Output Formatters for formats like Postman Collections, Insomnia exports, or specific SDK stubs.
  • Interactive Features: Integrate with client-side JavaScript for "Try It Out" functionality directly within the generated HTML documentation.
  • Customization: Allow users to inject custom CSS/JS, override templates, or define custom content blocks.
  • Internationalization (i18n): Architect the content generation to support multiple languages for documentation.

This architectural plan lays a solid foundation for developing a powerful and versatile API Documentation Generator, capable of meeting diverse documentation needs.

gemini Output

This deliverable provides a comprehensive, detailed, and professional API Documentation Generator. This tool is designed to automate the creation of API documentation from an OpenAPI (Swagger) specification, generating human-readable Markdown files that can then be easily converted into various formats (HTML, PDF, etc.).

The generated code is clean, well-commented, and production-ready, focusing on clarity, modularity, and extensibility. It leverages popular Python libraries like PyYAML for parsing API specifications and Jinja2 for flexible templating.


API Documentation Generator

This section outlines the core components and usage of the API Documentation Generator.

1. Introduction

The api_doc_generator is a Python-based tool that takes an OpenAPI 3.x specification (YAML or JSON) as input and generates structured Markdown documentation. This documentation includes:

  • API Overview: General information about the API.
  • Authentication Guide: Details on how to authenticate requests.
  • Endpoint Descriptions: Detailed information for each API endpoint, including method, path, summary, description, parameters, request bodies, and responses.
  • Request/Response Examples: Illustrative examples for various operations.
  • Data Models (Schemas): Definitions of the data structures used in the API.
  • SDK Usage Examples: Placeholder for integrating language-specific SDK examples or generic cURL commands.

2. Core Concepts

The generator operates on the following principles:

  • OpenAPI Specification as Source of Truth: The tool relies entirely on a valid OpenAPI specification to extract all necessary information.
  • Templating for Flexibility: Jinja2 templates are used to define the structure and content of the generated Markdown files, allowing for easy customization of the documentation's look and feel.
  • Modular Output: Documentation is organized into logical files (e.g., index.md, authentication.md, endpoints/.md, models/.md) for better navigability and maintainability.

3. Code Implementation

Below are the files comprising the API Documentation Generator.

3.1 api_doc_generator.py (Main Script)

This Python script orchestrates the entire documentation generation process.


import yaml
import os
import re
from jinja2 import Environment, FileSystemLoader, select_autoescape

class APIDocGenerator:
    def __init__(self, spec_path, output_dir, templates_dir="templates"):
        """
        Initializes the API Documentation Generator.

        Args:
            spec_path (str): Path to the OpenAPI specification file (YAML or JSON).
            output_dir (str): Directory where the generated documentation will be saved.
            templates_dir (str): Directory containing Jinja2 templates.
        """
        self.spec_path = spec_path
        self.output_dir = output_dir
        self.templates_dir = templates_dir
        self.spec = self._load_openapi_spec()
        self.template_env = self._setup_jinja_env()

        # Ensure output directory exists
        os.makedirs(self.output_dir, exist_ok=True)
        os.makedirs(os.path.join(self.output_dir, "endpoints"), exist_ok=True)
        os.makedirs(os.path.join(self.output_dir, "models"), exist_ok=True)

    def _load_openapi_spec(self):
        """Loads and parses the OpenAPI specification from the given path."""
        try:
            with open(self.spec_path, 'r', encoding='utf-8') as f:
                if self.spec_path.endswith('.yaml') or self.spec_path.endswith('.yml'):
                    return yaml.safe_load(f)
                elif self.spec_path.endswith('.json'):
                    import json
                    return json.load(f)
                else:
                    raise ValueError("Unsupported file format. Please use .yaml, .yml, or .json.")
        except FileNotFoundError:
            print(f"Error: OpenAPI specification file not found at {self.spec_path}")
            exit(1)
        except yaml.YAMLError as e:
            print(f"Error parsing YAML specification: {e}")
            exit(1)
        except json.JSONDecodeError as e:
            print(f"Error parsing JSON specification: {e}")
            exit(1)

    def _setup_jinja_env(self):
        """Sets up the Jinja2 environment for template loading."""
        loader = FileSystemLoader(self.templates_dir)
        return Environment(
            loader=loader,
            autoescape=select_autoescape(['html', 'xml', 'md']),
            trim_blocks=True,
            lstrip_blocks=True
        )

    def _render_and_save(self, template_name, context, output_file):
        """Renders a Jinja2 template with the given context and saves it to a file."""
        template = self.template_env.get_template(template_name)
        content = template.render(context)
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(content)
        print(f"Generated: {output_file}")

    def _sanitize_filename(self, name):
        """Sanitizes a string to be used as a filename."""
        name = re.sub(r'[^\w\s-]', '', name).strip()
        name = re.sub(r'[-\s]+', '-', name)
        return name.lower()

    def generate_index_page(self):
        """Generates the main index page (index.md)."""
        info = self.spec.get('info', {})
        context = {
            'api_title': info.get('title', 'API Documentation'),
            'api_version': info.get('version', '1.0.0'),
            'api_description': info.get('description', 'No description provided.'),
            'servers': self.spec.get('servers', [])
        }
        self._render_and_save(
            'index.md.j2',
            context,
            os.path.join(self.output_dir, 'index.md')
        )

    def generate_authentication_guide(self):
        """Generates the authentication guide (authentication.md)."""
        security_schemes = self.spec.get('components', {}).get('securitySchemes', {})
        context = {
            'security_schemes': security_schemes
        }
        self._render_and_save(
            'authentication.md.j2',
            context,
            os.path.join(self.output_dir, 'authentication.md')
        )

    def generate_endpoints_documentation(self):
        """Generates individual documentation files for each API endpoint."""
        paths = self.spec.get('paths', {})
        for path, methods in paths.items():
            for method, details in methods.items():
                if method.lower() not in ['get', 'post', 'put', 'delete', 'patch', 'head', 'options', 'trace']:
                    continue # Skip non-HTTP methods or custom extensions

                operation_id = details.get('operationId')
                if not operation_id:
                    # Create a default operationId if not provided
                    operation_id = f"{method.lower()}_{self._sanitize_filename(path).replace('/', '_')}"

                # Extract request body details
                request_body = None
                if 'requestBody' in details:
                    content = details['requestBody'].get('content', {})
                    for media_type, media_details in content.items():
                        request_body = {
                            'media_type': media_type,
                            'schema': media_details.get('schema'),
                            'example': media_details.get('example') or media_details.get('examples', {}).get('default', {}).get('value')
                        }
                        break # Take the first one if multiple media types

                # Extract responses
                responses = []
                for status_code, response_details in details.get('responses', {}).items():
                    response_content = response_details.get('content', {})
                    example = None
                    schema = None
                    for media_type, media_details in response_content.items():
                        schema = media_details.get('schema')
                        example = media_details.get('example') or media_details.get('examples', {}).get('default', {}).get('value')
                        break # Take the first one

                    responses.append({
                        'status_code': status_code,
                        'description': response_details.get('description', 'No description.'),
                        'schema': schema,
                        'example': example
                    })

                context = {
                    'operation_id': operation_id,
                    'method': method.upper(),
                    'path': path,
                    'summary': details.get('summary', ''),
                    'description': details.get('description', 'No description provided.'),
                    'tags': details.get('tags', []),
                    'parameters': details.get('parameters', []),
                    'request_body': request_body,
                    'responses': responses,
                    'security': details.get('security', self.spec.get('security', [])) # Endpoint specific security or global
                }
                filename = f"{self._sanitize_filename(operation_id)}.md"
                self._render_and_save(
                    'endpoint.md.j2',
                    context,
                    os.path.join(self.output_dir, 'endpoints', filename)
                )

    def generate_models_documentation(self):
        """Generates individual documentation files for each data model (schema)."""
        schemas = self.spec.get('components', {}).get('schemas', {})
        for schema_name, schema_details in schemas.items():
            context = {
                'schema_name': schema_name,
                'description': schema_details.get('description', 'No description provided.'),
                'type': schema_details.get('type', 'object'),
                'properties': schema_details.get('properties', {}),
                'required_properties': schema_details.get('required', [])
            }
            filename = f"{self._sanitize_filename(schema_name)}.md"
            self._render_and_save(
                'model.md.j2',
                context,
                os.path.join(self.output_dir, 'models', filename)
            )

    def generate_all_documentation(self):
        """Generates all types of documentation."""
        print(f"Generating documentation for '{self.spec.get('info', {}).
gemini Output

As a professional AI assistant within PantheraHive, I am pleased to present the comprehensive and detailed API documentation for your service. This documentation is designed to be a definitive resource for developers, providing clear instructions, examples, and best practices for integrating with your API.


PantheraHive Project Management API Documentation

Welcome to the PantheraHive Project Management API documentation! This guide provides detailed information on how to interact with our API to manage projects, tasks, users, and more. Our API is designed to be RESTful, making it easy to understand and use.

1. Introduction

The PantheraHive Project Management API allows developers to programmatically access and manage project data, including creating projects, assigning tasks, updating statuses, and retrieving project-related information. This documentation covers authentication, available endpoints, data models, error handling, and SDK usage examples to help you get started quickly.

2. Base URL

All API requests should be made to the following base URL:

https://api.pantherahive.com/v1

3. Authentication

The PantheraHive API uses API Key authentication. To access protected endpoints, you must include your unique API key in the Authorization header of every request.

3.1 Obtaining Your API Key

  1. Log in to your PantheraHive developer dashboard.
  2. Navigate to the "API Keys" section.
  3. Generate a new API key or use an existing one.
  4. Keep your API key secure and do not share it publicly.

3.2 Authenticating Requests

Include your API key in the Authorization header with the Bearer scheme:


Authorization: Bearer YOUR_API_KEY

Example (cURL):


curl -X GET \
  https://api.pantherahive.com/v1/projects \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json'

4. Rate Limiting

To ensure fair usage and system stability, the PantheraHive API enforces rate limits.

  • Limit: 100 requests per minute per API key.
  • Exceeding the limit: Requests exceeding the rate limit will receive a 429 Too Many Requests HTTP status code.

Rate Limit Headers:

The following headers are included in every API response to help you monitor your usage:

| Header | Description |

| :----------------- | :--------------------------------------------------- |

| X-RateLimit-Limit| The maximum number of requests allowed in the window.|

| X-RateLimit-Remaining| The number of requests remaining in the current window.|

| X-RateLimit-Reset| The time (in UTC epoch seconds) when the current rate limit window resets.|

Example 429 Response:


HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1678886400

{
  "code": "TOO_MANY_REQUESTS",
  "message": "You have exceeded your rate limit. Please try again after the reset time."
}

5. Error Handling

The API uses standard HTTP status codes to indicate the success or failure of an API request. In case of an error, the response body will contain a JSON object with a code and message field, providing more details about the error.

| HTTP Status Code | Description | Error Code |

| :----------------- | :------------------------------------------- | :---------------------- |

| 200 OK | Request successful. | - |

| 201 Created | Resource created successfully. | - |

| 204 No Content | Request successful, no content to return. | - |

| 400 Bad Request | The request was malformed or invalid. | INVALID_INPUT |

| 401 Unauthorized | Authentication failed or not provided. | UNAUTHORIZED |

| 403 Forbidden | The authenticated user does not have permission to access the resource. | FORBIDDEN |

| 404 Not Found | The requested resource was not found. | RESOURCE_NOT_FOUND |

| 409 Conflict | The request could not be completed due to a conflict with the current state of the resource. | CONFLICT |

| 422 Unprocessable Entity | The request was well-formed but unable to be processed due to semantic errors. | VALIDATION_FAILED |

| 429 Too Many Requests | You have exceeded the API rate limit. | TOO_MANY_REQUESTS |

| 500 Internal Server Error | An unexpected error occurred on the server. | INTERNAL_SERVER_ERROR |

Example Error Response:


HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "code": "RESOURCE_NOT_FOUND",
  "message": "Project with ID 'proj_xyz123' not found."
}

6. Data Models

This section describes the core data structures used throughout the PantheraHive Project Management API.

6.1 Project Object

Represents a project within the system.

| Field | Type | Description |

| :---------- | :-------- | :---------------------------------------------- |

| id | string | Unique identifier for the project. (Read-only) |

| name | string | The name of the project. (Required) |

| description| string | A detailed description of the project. (Optional) |

| status | enum | Current status of the project (active, completed, on_hold, archived). (Default: active) |

| startDate | string | The project's start date (ISO 8601 format). (Optional) |

| endDate | string | The project's estimated end date (ISO 8601 format). (Optional) |

| ownerId | string | The ID of the user who owns the project. (Required) |

| teamIds | array<string> | An array of user IDs assigned to the project. (Optional) |

| createdAt | string | Timestamp when the project was created (ISO 8601). (Read-only) |

| updatedAt | string | Timestamp when the project was last updated (ISO 8601). (Read-only) |

Example Project Object:


{
  "id": "proj_abc123",
  "name": "Website Redesign",
  "description": "Redesign the company's main website to improve user experience and conversion rates.",
  "status": "active",
  "startDate": "2023-01-15T00:00:00Z",
  "endDate": "2023-06-30T23:59:59Z",
  "ownerId": "user_dev456",
  "teamIds": ["user_dev456", "user_qa789"],
  "createdAt": "2023-01-10T10:00:00Z",
  "updatedAt": "2023-03-01T14:30:00Z"
}

6.2 Task Object

Represents a task within a project.

| Field | Type | Description |

| :---------- | :-------- | :---------------------------------------------- |

| id | string | Unique identifier for the task. (Read-only) |

| projectId | string | The ID of the project this task belongs to. (Required) |

| title | string | The title of the task. (Required) |

| description| string | A detailed description of the task. (Optional) |

| status | enum | Current status of the task (pending, in_progress, completed, blocked). (Default: pending) |

| priority | enum | The priority level (low, medium, high). (Default: medium) |

| assigneeId| string | The ID of the user assigned to this task. (Optional) |

| dueDate | string | The task's due date (ISO 8601 format). (Optional) |

| createdAt | string | Timestamp when the task was created (ISO 8601). (Read-only) |

| updatedAt | string | Timestamp when the task was last updated (ISO 8601). (Read-only) |

Example Task Object:


{
  "id": "task_def456",
  "projectId": "proj_abc123",
  "title": "Design homepage mockups",
  "description": "Create high-fidelity mockups for the new website homepage, focusing on mobile-first design.",
  "status": "in_progress",
  "priority": "high",
  "assigneeId": "user_dev456",
  "dueDate": "2023-03-15T23:59:59Z",
  "createdAt": "2023-02-01T09:00:00Z",
  "updatedAt": "2023-02-10T11:00:00Z"
}

7. Endpoints

This section details all available API endpoints, their methods, parameters, and example requests/responses.


7.1 Projects

7.1.1 List Projects

Retrieve a list of all projects associated with the authenticated user.

  • Endpoint: GET /projects
  • Description: Returns a paginated list of projects.
  • Query Parameters:

| Parameter | Type | Description | Default |

| :-------- | :------- | :---------------------------------------------- | :------- |

| status | enum | Filter projects by status (active, completed, on_hold, archived). | active |

| ownerId | string | Filter projects by the ID of the owner. | - |

| limit | integer| Maximum number of projects to return. | 10 |

| offset | integer| Number of projects to skip for pagination. | 0 |

  • Request Example (cURL):

    curl -X GET \
      'https://api.pantherahive.com/v1/projects?status=active&limit=5' \
      -H 'Authorization: Bearer YOUR_API_KEY' \
      -H 'Content-Type: application/json'
  • Response Example (200 OK):

    HTTP/1.1 200 OK
    Content-Type: application/json

    {
      "data": [
        {
          "id": "proj_abc123",
          "name": "Website Redesign",
          "status": "active",
          "ownerId": "user_dev456",
          "createdAt": "2023-01-10T10:00:00Z"
        },
        {
          "id": "proj_xyz789",
          "name": "Mobile App Development",
          "status": "active",
          "ownerId": "user_dev456",
          "createdAt": "2023-02-20T11:00:00Z"
        }
      ],
      "meta": {
        "total": 2,
        "limit": 5,
        "offset": 0
      }
    }

7.1.2 Create Project

Create a new project.

  • Endpoint: POST /projects
  • Description: Creates a new project with the provided details.
  • Request Body Parameters: See [Project Object](#61-project-object) for detailed schema.

* Required: name, ownerId

  • Request Example (cURL):

    curl -X POST \
      https://api.pantherahive.com/v1/projects \
      -H 'Authorization: Bearer YOUR_API_KEY' \
      -H 'Content-Type: application/json' \
      -d '{
            "name": "New Marketing Campaign",
            "description": "Plan and execute a new digital marketing campaign for Q3.",
            "ownerId": "user_dev456",
            "teamIds": ["user_qa789", "user_design101"]
          }'
  • Response Example (201 Created):

    HTTP/1.1 201 Created
    Content-Type: application/json

    {
      "id": "proj_new456",
      "name": "New Marketing Campaign",
      "description": "Plan and execute a new digital marketing campaign for Q3.",
      "status": "active",
      "ownerId": "user_dev456",
      "teamIds": ["user_qa789", "user_design101"],
      "createdAt": "2023-03-15T10:30:00Z",
      "updatedAt": "2023-03-15T10:30:00Z"
    }

7.1.3 Get Project by ID

Retrieve details for a specific project.

  • Endpoint: GET /projects/{projectId}
  • Description: Returns the full details of a project specified by its ID.
  • Path Parameters:

| Parameter | Type | Description |

| :---------- | :------- | :------------------------------ |

| projectId | string | The unique ID of the project. |

  • Request Example (cURL):

    curl -X GET \
      https://api.pantherahive.com/v1/projects/proj_abc123 \
      -H 'Authorization: Bearer YOUR_API_KEY' \
      -H 'Content-Type: application/json'
  • Response Example (200 OK):

    HTTP/1.1 200 OK
    Content-Type: application/json

    {
      "id": "proj_abc123",
      "name": "Website Redesign",
      "description": "Redesign the company's main website to improve user experience and conversion rates.",
      "status": "active",
      "startDate": "2023-01-15T00:00:00Z",
      "endDate": "2023-06-30T23:59:59Z",
api_documentation_generator.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}