API Documentation Generator
Run ID: 69cc6b793e7fb09ff16a1b8a2026-04-01Development
PantheraHive BOS
BOS Dashboard

This document outlines the detailed architectural plan for the "API Documentation Generator." This plan focuses on creating a robust, extensible, and maintainable system capable of generating professional API documentation from various sources, including endpoint descriptions, request/response examples, authentication guides, and SDK usage examples.

1. System Overview and Goals

The primary goal of the API Documentation Generator is to automate the creation of high-quality, comprehensive, and user-friendly API documentation. It aims to reduce manual effort, ensure consistency, and support multiple output formats and input sources.

Key Objectives:

2. High-Level Architecture

The API Documentation Generator will follow a modular, pipeline-based architecture, consisting of distinct stages: Input Parsing, Internal Representation, Processing/Enrichment, and Output Generation.

mermaid • 618 chars
graph TD
    A[API Definition Sources] --> B(Input Adapters/Parsers);
    B --> C(Internal Data Model / Intermediate Representation);
    C --> D{Processing & Enrichment};
    D --> E(Templating Engine);
    E --> F{Output Formatters};
    F --> G[Generated Documentation];

    subgraph "Processing & Enrichment"
        D1[Authentication Handler]
        D2[Example Generator]
        D3[SDK Usage Example Generator]
        D4[Schema Resolver]
    end

    subgraph "Output Formatters"
        F1[HTML Renderer]
        F2[Markdown Renderer]
        F3[PDF Exporter]
        F4[Postman Collection Exporter]
    end
Sandboxed live preview

3. Core Architectural Components

3.1. Input Adapters / Parsers Layer

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

  • OpenAPI/Swagger Parser: A dedicated module to parse OpenAPI Specification (OAS) JSON/YAML files (versions 2.0 and 3.x). This will be a primary input source due to its widespread adoption.
  • Postman Collection Parser: A module to parse Postman Collection JSON files, extracting requests, responses, variables, and authentication details.
  • Custom/Code Annotation Parser (Future Consideration): An extensible interface to allow for parsing custom DSLs or extracting API definitions directly from code annotations (e.g., JSDoc, PHPDoc, Go annotations).
  • Validation Module: Ensures that the parsed input conforms to its respective schema and is valid before further processing.

3.2. Internal Data Model (Intermediate Representation)

This is the central, technology-agnostic representation of the API. It acts as the canonical source of truth for all API information within the generator. This model will be highly structured and normalized.

  • API Object: Root object containing global information (title, version, description, servers, security schemes).
  • Endpoint Object: Represents a specific API path (e.g., /users/{id}).

* Method Object: Represents an HTTP method for an endpoint (GET, POST, PUT, DELETE).

* Parameters: Path, query, header, cookie parameters (name, type, required, description, schema).

* Request Body: Content types, schemas, examples.

* Responses: Status codes, descriptions, headers, content types, schemas, examples.

* Security Requirements: Specific security schemes applicable to this method.

  • Schema Object: Reusable data models (JSON Schema based) for requests, responses, and parameters.
  • Security Scheme Object: Definitions for various authentication methods (API Key, OAuth2, Bearer Token, Basic Auth).
  • Tag Object: For grouping related endpoints.
  • Example Object: Reusable examples for parameters, request bodies, and responses.

3.3. Processing & Enrichment Layer

This layer takes the raw internal data model and enriches it with additional information or transformations required for high-quality documentation.

  • Authentication Handler: Resolves and applies security schemes to endpoints, generating clear authentication instructions.
  • Example Generator:

* Schema-to-Example Converter: Automatically generates realistic JSON/XML examples from defined schemas.

* Example Injector: Integrates user-provided examples directly into the documentation.

  • SDK Usage Example Generator:

* Language-Specific Templates: Utilizes templates (e.g., for Python, JavaScript, cURL, Ruby) to generate code snippets demonstrating how to interact with each endpoint, including authentication.

* Dynamic Parameter Insertion: Fills in example values for parameters into the generated code.

  • Schema Resolver: Resolves $ref references within the internal data model to provide a fully dereferenced view for documentation generation, ensuring all schema details are readily available.
  • Markdown/HTML Sanitizer: Ensures descriptions and other text fields are safe for rendering in various output formats.

3.4. Templating Engine

This component is responsible for combining the processed internal data model with predefined templates to render the final documentation structure.

  • Template Language: A robust and flexible templating language (e.g., Jinja2 for Python, Handlebars for Node.js, Go's text/template) will be used to define the layout and styling of the documentation.
  • Modular Templates: Templates will be broken down into reusable partials (e.g., header, footer, endpoint card, parameter table, schema definition).
  • Customization Support: Allow users to provide their own templates or override specific partials for custom branding and styling.

3.5. Output Formatters / Renderers Layer

This layer takes the rendered content from the templating engine and transforms it into the desired final output format.

  • HTML Renderer: Generates a complete, navigatable static HTML website. This will include CSS styling, JavaScript for interactive elements (e.g., collapsable sections, syntax highlighting).
  • Markdown Renderer: Outputs documentation in Markdown format, suitable for READMEs, Wikis, or further conversion.
  • PDF Exporter: Converts the HTML output into a professional PDF document, suitable for offline viewing or printing. This may involve headless browser rendering (e.g., Puppeteer, WeasyPrint).
  • Postman Collection Exporter: Generates an updated Postman Collection JSON, allowing users to import the documented API directly into Postman for testing.

4. Data Flow

  1. Input: The generator receives an API definition file (e.g., openapi.yaml, postman_collection.json).
  2. Parsing: The appropriate Input Adapter (e.g., OpenAPI Parser) reads the file and parses its content into a raw, unvalidated object structure.
  3. Validation: The parsed structure is validated against its respective schema (e.g., OpenAPI Schema).
  4. Internal Model Conversion: The validated data is transformed into the Generator's Internal Data Model, ensuring consistency and normalization across different input sources.
  5. Enrichment: The Processing & Enrichment layer adds details:

* Authentication Handler creates authentication guides.

* Example Generator produces or integrates request/response examples.

* SDK Usage Example Generator creates code snippets.

* Schema Resolver dereferences schemas.

  1. Templating: The enriched Internal Data Model is fed into the Templating Engine, which applies the chosen documentation templates.
  2. Rendering: The Templating Engine produces the structured content (e.g., HTML fragments, Markdown text).
  3. Formatting: The Output Formatters take the rendered content and convert it into the final output format (HTML files, a single Markdown file, a PDF document, a Postman Collection).
  4. Output: The generated documentation files are saved to a specified output directory or made available for download/deployment.

5. Technology Stack Recommendations

To ensure robustness, extensibility, and good community support, the following technology stack is recommended:

  • Primary Language: Python (or Node.js, depending on existing team expertise). Python offers excellent libraries for parsing YAML/JSON, templating (Jinja2), and potentially PDF generation (WeasyPrint).
  • API Parsing:

* PyYAML / json for basic file handling.

* openapi-spec-validator (Python) or swagger-parser (Node.js) for OpenAPI parsing and validation.

* Custom parsers for Postman Collections.

  • Internal Data Model: Python dataclasses or Pydantic models for strong typing and validation.
  • Templating Engine: Jinja2 (Python) or Handlebars.js (Node.js) for flexible and powerful templating.
  • PDF Generation: WeasyPrint (Python, HTML/CSS to PDF) or Puppeteer (Node.js, headless Chrome for rendering HTML to PDF).
  • Command-Line Interface (CLI): Click (Python) or Commander.js (Node.js) for an intuitive user experience.
  • Testing: Pytest (Python) or Jest (Node.js) for comprehensive unit and integration testing.

6. Key Architectural Principles

  • Modularity: Each component (parser, processor, renderer) will be a distinct, loosely coupled module with well-defined interfaces. This allows for independent development, testing, and replacement.
  • Extensibility: The design will prioritize adding new input formats, output formats, and SDK languages without modifying core components. This will be achieved through plugin architectures or adapter patterns.
  • Configuration-Driven: The generator's behavior (input paths, output formats, template selection, customization options) will be controlled via configuration files (e.g., YAML, JSON), making it easy to use and adapt.
  • Idempotency: Running the generator multiple times with the same input should produce the exact same output.
  • Separation of Concerns: Distinct layers for parsing, data modeling, processing, and rendering.

7. Deployment Considerations

  • CLI Tool: The generator will primarily function as a command-line interface (CLI) tool, runnable locally or within CI/CD pipelines. This makes it highly portable and automatable.
  • Docker Container: Provide a Docker image for easy deployment and consistent environments across different operating systems.
  • Static Site Hosting: Generated HTML documentation can be easily deployed to static site hosting services (e.g., Netlify, GitHub Pages, AWS S3) for cost-effective and scalable hosting.

8. Future Enhancements (Architectural Hooks)

The proposed architecture includes several points of extensibility for future features:

  • Interactive UI/Web Service: The core logic is decoupled enough to be wrapped in a web service or an interactive UI (e.g., a Flask/Django app or a Node.js Express app with a React/Vue frontend).
  • Version Control Integration: Automatically detect API definition changes from Git repositories.
  • Feedback/Comment System: Integration with external commenting platforms for user feedback on documentation.
  • Search Functionality: Incorporate client-side search indexing for generated HTML documentation.
  • Internationalization (i18n): Support for generating documentation in multiple languages.
  • Customization via CSS/JS: Provide clear mechanisms for users to inject custom CSS and JavaScript into the generated HTML.

This architectural plan provides a solid foundation for building a powerful and flexible API Documentation Generator. The modular approach ensures that the system can evolve to meet future requirements and integrate with a wide array of tools and workflows.

gemini Output

As a professional AI assistant within PantheraHive, I've generated comprehensive and detailed API documentation for the Product Catalog API. This documentation is designed to be clear, actionable, and ready for your customers. It includes a general overview, authentication details, detailed endpoint descriptions with request/response examples, and SDK usage examples in Python.


Product Catalog API Documentation

Welcome to the Product Catalog API documentation. This API allows developers to programmatically manage products, including retrieving, creating, updating, and deleting product information within your catalog.

1. Introduction

The Product Catalog API provides a robust and scalable way to interact with your product data. It's designed for e-commerce platforms, inventory management systems, and other applications requiring programmatic access to product information.

  • Base URL: https://api.example.com/v1
  • API Version: 1.0
  • Data Format: All requests and responses are handled in JSON format.
  • Rate Limiting: Default rate limit is 100 requests per minute per API Key. Exceeding this limit will result in a 429 Too Many Requests error.

2. Authentication

The Product Catalog API uses API Key authentication. Your API Key must be included in the X-API-Key header for every request.

How to obtain your API Key:

  1. Log in to your developer dashboard at https://developer.example.com.
  2. Navigate to the "API Keys" section.
  3. Generate a new API Key if you don't have one, or use an existing one.
  4. Keep your API Key secure and do not share it publicly.

Example Authentication Header:


X-API-Key: YOUR_SECURE_API_KEY_HERE

Example cURL with Authentication:


curl -X GET \
  https://api.example.com/v1/products \
  -H 'X-API-Key: YOUR_SECURE_API_KEY_HERE'

3. Endpoints

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

3.1. List All Products

Retrieve a list of all products in the catalog, with optional filtering and pagination.

  • HTTP Method: GET
  • URL Path: /products

Query Parameters:

| Parameter | Type | Description | Required | Example |

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

| limit | Integer | Maximum number of products to return (1-100). | Optional | 10 |

| offset | Integer | Number of products to skip for pagination. | Optional | 0 |

| category| String | Filter products by category. | Optional | electronics|

| min_price| Float | Filter products with price greater than or equal to this value. | Optional | 50.00 |

| max_price| Float | Filter products with price less than or equal to this value. | Optional | 200.00|

Example Request (cURL):


curl -X GET \
  'https://api.example.com/v1/products?limit=5&category=electronics' \
  -H 'X-API-Key: YOUR_SECURE_API_KEY_HERE' \
  -H 'Content-Type: application/json'

Example Response (200 OK):


{
  "total": 2,
  "limit": 5,
  "offset": 0,
  "products": [
    {
      "id": "prod_12345",
      "name": "Wireless Bluetooth Headphones",
      "description": "High-fidelity sound with active noise cancellation.",
      "price": 199.99,
      "currency": "USD",
      "category": "electronics",
      "sku": "WH-BT-HP-001",
      "stock": 150,
      "created_at": "2023-01-15T10:00:00Z",
      "updated_at": "2023-01-15T10:00:00Z"
    },
    {
      "id": "prod_67890",
      "name": "Smartwatch Pro X",
      "description": "Track your fitness, receive notifications, and more.",
      "price": 249.99,
      "currency": "USD",
      "category": "electronics",
      "sku": "SW-PX-002",
      "stock": 80,
      "created_at": "2023-02-20T14:30:00Z",
      "updated_at": "2023-02-20T14:30:00Z"
    }
  ]
}

3.2. Get Product by ID

Retrieve detailed information for a single product using its unique ID.

  • HTTP Method: GET
  • URL Path: /products/{productId}

Path Parameters:

| Parameter | Type | Description | Required | Example |

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

| productId | String | The unique identifier of the product. | Yes | prod_12345 |

Example Request (cURL):


curl -X GET \
  https://api.example.com/v1/products/prod_12345 \
  -H 'X-API-Key: YOUR_SECURE_API_KEY_HERE' \
  -H 'Content-Type: application/json'

Example Response (200 OK):


{
  "id": "prod_12345",
  "name": "Wireless Bluetooth Headphones",
  "description": "High-fidelity sound with active noise cancellation.",
  "price": 199.99,
  "currency": "USD",
  "category": "electronics",
  "sku": "WH-BT-HP-001",
  "stock": 150,
  "created_at": "2023-01-15T10:00:00Z",
  "updated_at": "2023-01-15T10:00:00Z"
}

Example Error Response (404 Not Found):


{
  "code": "product_not_found",
  "message": "Product with ID 'non_existent_id' was not found."
}

3.3. Create a New Product

Add a new product to the catalog.

  • HTTP Method: POST
  • URL Path: /products

Request Body Parameters:

| Parameter | Type | Description | Required | Example |

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

| name | String | The name of the product. | Yes | Gaming Mouse|

| description| String | A detailed description of the product. | Yes | Ergonomic design with programmable buttons. |

| price | Float | The price of the product. | Yes | 79.99 |

| currency | String | The currency of the product price (e.g., USD, EUR). | Yes | USD |

| category | String | The category the product belongs to. | Yes | peripherals |

| sku | String | Stock Keeping Unit (unique identifier for inventory). | Yes | GM-PRO-003 |

| stock | Integer| Current stock level of the product. | Yes | 200 |

| image_url | String | URL to the product's main image. | Optional | https://example.com/img/gm-pro.jpg |

Example Request (cURL):


curl -X POST \
  https://api.example.com/v1/products \
  -H 'X-API-Key: YOUR_SECURE_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Mechanical Keyboard RGB",
    "description": "Tactile mechanical switches with customizable RGB lighting.",
    "price": 129.99,
    "currency": "USD",
    "category": "peripherals",
    "sku": "MK-RGB-001",
    "stock": 100,
    "image_url": "https://example.com/images/mk_rgb.jpg"
  }'

Example Response (201 Created):


{
  "id": "prod_abcde",
  "name": "Mechanical Keyboard RGB",
  "description": "Tactile mechanical switches with customizable RGB lighting.",
  "price": 129.99,
  "currency": "USD",
  "category": "peripherals",
  "sku": "MK-RGB-001",
  "stock": 100,
  "image_url": "https://example.com/images/mk_rgb.jpg",
  "created_at": "2023-03-01T09:15:00Z",
  "updated_at": "2023-03-01T09:15:00Z"
}

Example Error Response (400 Bad Request):


{
  "code": "validation_error",
  "message": "Invalid input for product creation.",
  "details": [
    {
      "field": "name",
      "error": "Product name is required."
    },
    {
      "field": "price",
      "error": "Price must be a positive number."
    }
  ]
}

3.4. Update an Existing Product

Modify the details of an existing product. Only provide the fields you wish to update.

  • HTTP Method: PUT
  • URL Path: /products/{productId}

Path Parameters:

| Parameter | Type | Description | Required | Example |

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

| productId | String | The unique identifier of the product. | Yes | prod_12345 |

Request Body Parameters (all optional, but at least one must be provided):

| Parameter | Type | Description | Required | Example |

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

| name | String | The updated name of the product. | Optional | Wireless Headphones Pro|

| description| String | An updated description of the product. | Optional | Improved battery life, enhanced bass. |

| price | Float | The updated price of the product. | Optional | 219.99 |

| currency | String | The updated currency of the product price. | Optional | EUR |

| category | String | The updated category the product belongs to. | Optional | audio |

| sku | String | Updated Stock Keeping Unit. | Optional | WH-BT-HP-PRO-001|

| stock | Integer| Updated current stock level. | Optional | 120 |

| image_url | String | Updated URL to the product's main image. | Optional | https://example.com/img/wh-pro.jpg |

Example Request (cURL):


curl -X PUT \
  https://api.example.com/v1/products/prod_12345 \
  -H 'X-API-Key: YOUR_SECURE_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "price": 219.99,
    "stock": 120,
    "description": "Improved battery life, enhanced bass, and new color options."
  }'

Example Response (200 OK):


{
  "id": "prod_12345",
  "name": "Wireless Bluetooth Headphones",
  "description": "Improved battery life, enhanced bass, and new color options.",
  "price": 219.99,
  "currency": "USD",
  "category": "electronics",
  "sku": "WH-BT-HP-001",
  "stock": 120,
  "created_at": "2023-01-15T10:00:00Z",
  "updated_at": "2023-03-05T11:00:00Z"
}

3.5. Delete a Product

Remove a product from the catalog.

  • HTTP Method: DELETE
  • URL Path: /products/{productId}

Path Parameters:

| Parameter | Type | Description | Required | Example |

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

| productId | String | The unique identifier of the product. | Yes | prod_67890 |

Example Request (cURL):


curl -X DELETE \
  https://api.example.com/v1/products/prod_67890 \
  -H 'X-API-Key: YOUR_SECURE_API_KEY_HERE' \
  -H 'Content-Type: application/json'

Example Response (204 No Content):

A successful deletion will return a 204 No Content status code with an empty response body.

Example Error Response (404 Not Found):


{
  "code": "product_not_found",
gemini Output

We are pleased to present the comprehensive API Documentation for the PantheraHive Workflow API. This document serves as a complete guide for developers to integrate with our powerful workflow automation platform, enabling programmatic access to manage, execute, and monitor your workflows.

Our goal is to provide clear, concise, and actionable information, ensuring a smooth development experience.


PantheraHive Workflow API Documentation

1. Introduction

The PantheraHive Workflow API provides a robust set of endpoints to programmatically interact with your workflows. You can manage workflow definitions, trigger executions, retrieve status updates, and integrate PantheraHive's automation capabilities directly into your applications.

Key Features:

  • Workflow Management: Create, retrieve, update, and delete workflow definitions.
  • Workflow Execution: Trigger new workflow runs and monitor their status.
  • Data Integration: Pass input data to workflows and retrieve output results.
  • Secure Access: Authenticate securely using API Keys or OAuth 2.0.

Base URL:

All API requests should be prefixed with the following base URL:

https://api.pantherahive.com/v1


2. Authentication

The PantheraHive Workflow API supports two primary methods for authentication: API Keys and OAuth 2.0.

2.1. API Key Authentication

For quick integration and server-to-server communication, you can use an API Key.

How to Obtain an API Key:

  1. Log in to your PantheraHive dashboard.
  2. Navigate to "Settings" -> "API Keys".
  3. Generate a new API Key. Ensure you store it securely, as it will only be shown once.

How to Use an API Key:

Include your API Key in the Authorization header of every request, prefixed with Bearer.

Example:


Authorization: Bearer YOUR_API_KEY

cURL Example:


curl -X GET \
  https://api.pantherahive.com/v1/workflows \
  -H 'Authorization: Bearer YOUR_API_KEY'

2.2. OAuth 2.0 Authentication

For applications requiring user consent and delegated access (e.g., third-party integrations), OAuth 2.0 is the recommended method.

Supported Grant Types:

  • Authorization Code Grant: For web applications.
  • Client Credentials Grant: For server-to-server applications that do not involve user interaction.

OAuth 2.0 Flow (Authorization Code Grant):

  1. Register Your Application:

* Log in to your PantheraHive dashboard.

* Navigate to "Settings" -> "Applications" and register a new application.

* You will receive a client_id and client_secret. Configure your redirect_uri.

  1. Request User Authorization:

Redirect your user to the PantheraHive authorization URL:


    GET https://api.pantherahive.com/oauth/authorize
        ?response_type=code
        &client_id=YOUR_CLIENT_ID
        &redirect_uri=YOUR_REDIRECT_URI
        &scope=workflow:read workflow:write workflow:execute
        &state=OPTIONAL_STATE_VALUE

* scope: Define the permissions your application needs (e.g., workflow:read, workflow:write, workflow:execute).

  1. Exchange Authorization Code for Access Token:

After the user grants permission, they will be redirected to your redirect_uri with an authorization_code. Exchange this code for an access_token and refresh_token:


    curl -X POST \
      https://api.pantherahive.com/oauth/token \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      -d 'grant_type=authorization_code&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&code=AUTHORIZATION_CODE&redirect_uri=YOUR_REDIRECT_URI'

Response Example:


    {
      "access_token": "YOUR_ACCESS_TOKEN",
      "token_type": "Bearer",
      "expires_in": 3600,
      "refresh_token": "YOUR_REFRESH_TOKEN",
      "scope": "workflow:read workflow:write workflow:execute"
    }
  1. Use Access Token:

Include the access_token in the Authorization header, prefixed with Bearer, similar to API Key authentication.

Example:


    Authorization: Bearer YOUR_ACCESS_TOKEN
  1. Refresh Access Token:

When your access_token expires, use the refresh_token to obtain a new one:


    curl -X POST \
      https://api.pantherahive.com/oauth/token \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      -d 'grant_type=refresh_token&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&refresh_token=YOUR_REFRESH_TOKEN'

3. Error Handling

The PantheraHive Workflow API uses standard HTTP status codes to indicate the success or failure of an API request. In case of an error, the API will return a JSON object containing details about the error.

3.1. Common HTTP Status Codes

| Status Code | Meaning | Description |

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

| 200 OK | Success | The request was successful. |

| 201 Created | Resource Created | The request resulted in a new resource being created. |

| 204 No Content | No Content | The request was successful, but there is no content to return (e.g., DELETE). |

| 400 Bad Request | Invalid Request | The request was malformed or missing required parameters. |

| 401 Unauthorized | Authentication Required | Authentication credentials were missing or invalid. |

| 403 Forbidden | Insufficient Permissions | The authenticated user does not have permission to perform the action. |

| 404 Not Found | Resource Not Found | The requested resource does not exist. |

| 405 Method Not Allowed | Method Not Allowed | The HTTP method used is not supported for this endpoint. |

| 429 Too Many Requests | Rate Limit Exceeded | You have sent too many requests in a given amount of time. |

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

3.2. Error Response Structure

When an error occurs, the API will return a JSON object with the following structure:


{
  "code": "ERROR_CODE_STRING",
  "message": "A human-readable description of the error.",
  "details": [
    {
      "field": "parameter_name",
      "message": "Specific reason for the parameter error."
    }
  ],
  "trace_id": "UNIQUE_REQUEST_IDENTIFIER"
}

Example 400 Bad Request Response:


{
  "code": "INVALID_INPUT",
  "message": "The request body contains invalid data.",
  "details": [
    {
      "field": "name",
      "message": "Workflow name cannot be empty."
    },
    {
      "field": "steps[0].action",
      "message": "Invalid action type 'unknown_action'."
    }
  ],
  "trace_id": "a1b2c3d4e5f6g7h8i9j0"
}

4. Rate Limiting

To ensure fair usage and maintain API stability, the PantheraHive Workflow API implements rate limiting.

  • Limit: You are allowed to make 100 requests per minute per API Key or OAuth 2.0 access token.
  • Exceeding the Limit: If you exceed the rate limit, you will receive a 429 Too Many Requests HTTP status code.

4.1. Rate Limit Headers

The following HTTP headers are included in every API response to help you manage your request rate:

  • X-RateLimit-Limit: The maximum number of requests you can make in the current 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 Headers:


X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1678886400

5. Endpoints

This section details all available API endpoints, their methods, parameters, and provides request/response examples.

5.1. Workflow Object Structure

Throughout the API, a workflow object generally adheres to the following structure:


{
  "id": "wf_abcdef123456",
  "name": "My First Workflow",
  "description": "A simple workflow to process user input.",
  "status": "active",
  "created_at": "2023-01-15T10:00:00Z",
  "updated_at": "2023-01-15T10:00:00Z",
  "steps": [
    {
      "id": "step_1",
      "type": "trigger",
      "name": "Start",
      "config": {
        "input_schema": {
          "type": "object",
          "properties": {
            "userName": { "type": "string" },
            "userEmail": { "type": "string", "format": "email" }
          },
          "required": ["userName", "userEmail"]
        }
      }
    },
    {
      "id": "step_2",
      "type": "action",
      "name": "Send Welcome Email",
      "action_type": "email:send",
      "config": {
        "to": "{{steps.step_1.output.userEmail}}",
        "subject": "Welcome, {{steps.step_1.output.userName}}!",
        "body": "Thank you for joining PantheraHive."
      }
    }
  ],
  "tags": ["onboarding", "email"]
}

5.2. List All Workflows

Retrieve a list of all workflow definitions associated with your account.

  • Endpoint: /workflows
  • Method: GET
  • Description: Returns a paginated list of workflow objects.
  • Authentication: Required

Parameters:

| Name | Type | Description | Required | Default |

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

| limit | integer | Maximum number of workflows to return per page. | Optional | 20 |

| offset | integer | The number of workflows to skip. | Optional | 0 |

| status | string | Filter workflows by their status (active, draft, archived). | Optional | All |

| tag | string | Filter workflows by a specific tag. | Optional | All |

Request Example:


curl -X GET \
  'https://api.pantherahive.com/v1/workflows?limit=10&status=active' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Response Example (200 OK):


{
  "data": [
    {
      "id": "wf_abcdef123456",
      "name": "User Onboarding",
      "description": "Automates the onboarding process for new users.",
      "status": "active",
      "created_at": "2023-01-15T10:00:00Z",
      "updated_at": "2023-03-01T11:30:00Z",
      "tags": ["onboarding", "automation"]
    },
    {
      "id": "wf_ghijkl789012",
      "name": "Daily Report Generation",
      "description": "Generates and sends daily summary reports.",
      "status": "active",
      "created_at": "2023-02-01T08:00:00Z",
      "updated_at": "2023-02-01T08:00:00Z",
      "tags": ["reporting", "scheduled"]
    }
  ],
  "metadata": {
    "total": 2,
    "limit": 10,
    "offset": 0
  }
}

5.3. Get a Specific Workflow

Retrieve the details of a single workflow definition by its ID.

  • Endpoint: /workflows/{workflow_id}
  • Method: GET
  • Description: Returns a single workflow object.
  • Authentication: Required

Parameters:

| Name | Type | Description | Required |

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

| workflow_id | string | The unique ID of the workflow. | Path |

Request Example:


curl -X GET \
  https://api.pantherahive.com/v1/workflows/wf_abcdef123456 \
  -H 'Authorization
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
"); 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' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')!).render( ) "); 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' import './App.css' function App(){ return(

"+slugTitle(pn)+"

Built with PantheraHive BOS

) } export default App "); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e} .app{min-height:100vh;display:flex;flex-direction:column} .app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px} h1{font-size:2.5rem;font-weight:700} "); 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)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` ## Open in IDE Open the project folder in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- 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",'{ "name": "'+pn+'", "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview" }, "dependencies": { "vue": "^3.5.13", "vue-router": "^4.4.5", "pinia": "^2.3.0", "axios": "^1.7.9" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.1", "typescript": "~5.7.3", "vite": "^6.0.5", "vue-tsc": "^2.2.0" } } '); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': resolve(__dirname,'src') } } }) "); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]} '); zip.file(folder+"tsconfig.app.json",'{ "compilerOptions":{ "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"], "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true, "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue", "strict":true,"paths":{"@/*":["./src/*"]} }, "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"] } '); zip.file(folder+"env.d.ts","/// "); zip.file(folder+"index.html"," "+slugTitle(pn)+"
"); 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' import { createPinia } from 'pinia' import App from './App.vue' import './assets/main.css' const app = createApp(App) app.use(createPinia()) app.mount('#app') "); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue"," "); 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} "); 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)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` Open in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- 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",'{ "name": "'+pn+'", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test" }, "dependencies": { "@angular/animations": "^19.0.0", "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", "@angular/core": "^19.0.0", "@angular/forms": "^19.0.0", "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { "@angular-devkit/build-angular": "^19.0.0", "@angular/cli": "^19.0.0", "@angular/compiler-cli": "^19.0.0", "typescript": "~5.6.0" } } '); zip.file(folder+"angular.json",'{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "'+pn+'": { "projectType": "application", "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/'+pn+'", "index": "src/index.html", "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "styles": ["src/styles.css"], "scripts": [] } }, "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"} } } } } '); zip.file(folder+"tsconfig.json",'{ "compileOnSave": false, "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"]}, "references":[{"path":"./tsconfig.app.json"}] } '); zip.file(folder+"tsconfig.app.json",'{ "extends":"./tsconfig.json", "compilerOptions":{"outDir":"./dist/out-tsc","types":[]}, "files":["src/main.ts"], "include":["src/**/*.d.ts"] } '); zip.file(folder+"src/index.html"," "+slugTitle(pn)+" "); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig) .catch(err => console.error(err)); "); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; } "); 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'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = '"+pn+"'; } "); zip.file(folder+"src/app/app.component.html","

"+slugTitle(pn)+"

Built with PantheraHive BOS

"); 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} "); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes) ] }; "); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router'; export const routes: Routes = []; "); 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)+" Generated by PantheraHive BOS. ## Setup ```bash npm install ng serve # or: npm start ``` ## Build ```bash ng build ``` Open in VS Code with Angular Language Service extension. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local .angular/ "); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/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(" "):"# add dependencies here "; zip.file(folder+"main.py",src||"# "+title+" # Generated by PantheraHive BOS print(title+" loaded") "); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ## Run ```bash python main.py ``` "); zip.file(folder+".gitignore",".venv/ __pycache__/ *.pyc .env .DS_Store "); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/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)+" "; zip.file(folder+"package.json",pkgJson); var fallback="const express=require("express"); const app=express(); app.use(express.json()); app.get("/",(req,res)=>{ res.json({message:""+title+" API"}); }); const PORT=process.env.PORT||3000; app.listen(PORT,()=>console.log("Server on port "+PORT)); "; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000 "); zip.file(folder+".gitignore","node_modules/ .env .DS_Store "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash npm install ``` ## Run ```bash npm run dev ``` "); } /* --- 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:" "+title+" "+code+" "; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */ *{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e} "); zip.file(folder+"script.js","/* "+title+" — scripts */ "); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Open Double-click `index.html` in your browser. Or serve locally: ```bash npx serve . # or python3 -m http.server 3000 ``` "); zip.file(folder+".gitignore",".DS_Store node_modules/ .env "); } /* ===== 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(/ {2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. Files: - "+app+".md (Markdown) - "+app+".html (styled HTML) "); } 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);}});}