AS
AgSkills.dev
MARKETPLACE

bunjs-apidog

Use when creating OpenAPI specs for Bun.js APIs, integrating with Apidog, documenting endpoints with schemas, or automating API specification imports via Apidog REST API. See bunjs for basics.

215
19

Preview

SKILL.md
name
bunjs-apidog
version
1.0.0
description
Use when creating OpenAPI specs for Bun.js APIs, integrating with Apidog, documenting endpoints with schemas, or automating API specification imports via Apidog REST API. See bunjs for basics.
plugin
dev
updated
2026-01-20

Bun.js OpenAPI and Apidog Integration

Overview

This skill covers OpenAPI specification creation and Apidog integration for Bun.js TypeScript backend applications. Learn how to document APIs with OpenAPI 3.0, use Apidog-specific extensions, import specifications via REST API, and maintain synchronized API documentation.

When to use this skill:

  • Creating OpenAPI specifications for API documentation
  • Synchronizing API specs with Apidog projects
  • Importing endpoints and schemas to Apidog
  • Managing API documentation lifecycle

See also:

  • dev:bunjs - Core Bun patterns, HTTP servers, database access
  • dev:bunjs-architecture - Layered architecture, camelCase conventions
  • dev:bunjs-production - Production deployment patterns

Why Apidog

Apidog is a comprehensive API development platform that combines:

  • API Design - Visual OpenAPI editor
  • API Documentation - Auto-generated, always up-to-date docs
  • API Testing - Built-in testing tools
  • API Mocking - Mock servers for frontend development
  • Team Collaboration - Shared workspace for teams

Environment Variables

Required:

APIDOG_PROJECT_ID=your-project-id # From Apidog project settings APIDOG_API_TOKEN=your-api-token # From Apidog account settings

How to get these:

  1. APIDOG_PROJECT_ID: Open your Apidog project β†’ Settings β†’ Project ID
  2. APIDOG_API_TOKEN: Apidog Account β†’ Settings β†’ API Tokens β†’ Generate Token

OpenAPI Spec Creation

Basic Structure

openapi: 3.0.0 info: title: My API version: 1.0.0 description: API for managing resources servers: - url: https://api.example.com/v1 description: Production server - url: https://staging-api.example.com/v1 description: Staging server - url: http://localhost:3000 description: Development server components: schemas: # Define reusable data models here securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT paths: # Define API endpoints here

Field Naming: camelCase (CRITICAL)

ALWAYS use camelCase for all JSON API field names in OpenAPI specs.

components: schemas: User: type: object required: - userId - emailAddress properties: userId: # βœ… camelCase type: string format: uuid emailAddress: # βœ… camelCase type: string format: email firstName: # βœ… camelCase type: string lastName: # βœ… camelCase type: string phoneNumber: # βœ… camelCase type: string isActive: # βœ… camelCase boolean type: boolean createdAt: # βœ… camelCase timestamp type: string format: date-time updatedAt: # βœ… camelCase timestamp type: string format: date-time # ❌ WRONG: snake_case # user_id, email_address, first_name, created_at # ❌ WRONG: PascalCase # UserId, EmailAddress, FirstName, CreatedAt

Why camelCase:

  • Native to JavaScript/JSON ecosystem
  • Industry standard (Google, Microsoft, AWS)
  • TypeScript friendly (1:1 mapping)
  • OpenAPI/Swagger convention
  • Auto-generated clients expect it

Schema Design

Define reusable schemas in components.schemas:

components: schemas: User: type: object required: - userId - emailAddress - firstName - lastName properties: userId: type: string format: uuid description: Unique user identifier emailAddress: type: string format: email description: User email address firstName: type: string minLength: 2 maxLength: 100 lastName: type: string minLength: 2 maxLength: 100 phoneNumber: type: string pattern: '^\+?[1-9]\d{1,14}$' role: type: string enum: [user, admin, moderator] default: user isActive: type: boolean default: true createdAt: type: string format: date-time updatedAt: type: string format: date-time CreateUserRequest: type: object required: - emailAddress - password - firstName - lastName properties: emailAddress: type: string format: email password: type: string format: password minLength: 8 firstName: type: string minLength: 2 lastName: type: string minLength: 2 phoneNumber: type: string role: type: string enum: [user, admin, moderator] UserListResponse: type: object properties: data: type: array items: $ref: '#/components/schemas/User' pagination: $ref: '#/components/schemas/Pagination' Pagination: type: object properties: page: type: integer minimum: 1 pageSize: type: integer minimum: 1 maximum: 100 total: type: integer totalPages: type: integer ErrorResponse: type: object properties: statusCode: type: integer type: type: string message: type: string details: type: array items: type: object properties: field: type: string message: type: string

Endpoint Definitions

Define endpoints in paths:

paths: /users: get: summary: List users description: Retrieve paginated list of users operationId: listUsers tags: - Users security: - bearerAuth: [] x-apidog-folder: User Management/Users x-apidog-status: released x-apidog-maintainer: backend-team parameters: - name: page in: query schema: type: integer minimum: 1 default: 1 - name: pageSize in: query schema: type: integer minimum: 1 maximum: 100 default: 20 - name: sortBy in: query schema: type: string enum: [createdAt, firstName, emailAddress] - name: orderBy in: query schema: type: string enum: [asc, desc] default: desc responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/UserListResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: summary: Create user description: Create a new user account operationId: createUser tags: - Users x-apidog-folder: User Management/Users x-apidog-status: released x-apidog-maintainer: backend-team requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' responses: '201': description: User created successfully content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/User' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: User already exists content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '422': description: Validation failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /users/{userId}: get: summary: Get user description: Retrieve a single user by ID operationId: getUser tags: - Users security: - bearerAuth: [] x-apidog-folder: User Management/Users x-apidog-status: released parameters: - name: userId in: path required: true schema: type: string format: uuid responses: '200': description: Successful response content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/User' '404': description: User not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse'

Apidog-Specific Extensions

x-apidog-folder

Organize endpoints in folders using / to separate levels:

paths: /users: post: x-apidog-folder: User Management/Users /users/{userId}/profile: get: x-apidog-folder: User Management/Users/Profile /orders: post: x-apidog-folder: Order Management/Orders

Escaping special characters:

  • Use \/ for /
  • Use \\ for \

x-apidog-status

Endpoint lifecycle status:

StatusDescription
designingBeing designed
pendingPending implementation
developingIn development
integratingIntegration phase
testingBeing tested
testedTesting complete
releasedProduction release
deprecatedMarked for deprecation
exceptionHas issues
obsoleteNo longer used
to be deprecatedWill be deprecated
paths: /users: post: x-apidog-status: released # Fully implemented /beta/feature: post: x-apidog-status: testing # In testing phase /legacy/api: get: x-apidog-status: deprecated # Being phased out

x-apidog-maintainer

Specify owner/maintainer (use Apidog username or nickname):

paths: /users: post: x-apidog-maintainer: backend-team /admin/settings: put: x-apidog-maintainer: john-doe

Importing to Apidog via REST API

Import Process

Step 1: Prepare OpenAPI Spec

Create a complete OpenAPI 3.0 spec in JSON format:

# Save spec to file cat > /tmp/api-spec.json << 'EOF' { "openapi": "3.0.0", "info": { ... }, "paths": { ... } } EOF

Step 2: Import via REST API

#!/bin/bash # Environment variables (from .env) APIDOG_PROJECT_ID="your-project-id" APIDOG_API_TOKEN="your-api-token" # Read OpenAPI spec OPENAPI_SPEC=$(cat /tmp/api-spec.json | jq -c .) # Import to Apidog curl -X POST "https://api.apidog.com/v1/projects/${APIDOG_PROJECT_ID}/import-openapi" \ -H "Authorization: Bearer ${APIDOG_API_TOKEN}" \ -H "X-Apidog-Api-Version: 2024-03-28" \ -H "Content-Type: application/json" \ -d "{ \"input\": \"${OPENAPI_SPEC}\", \"options\": { \"endpointOverwriteBehavior\": \"AUTO_MERGE\", \"schemaOverwriteBehavior\": \"AUTO_MERGE\", \"updateFolderOfChangedEndpoint\": false, \"prependBasePath\": false } }"

Import Behavior Options

OptionDescription
AUTO_MERGEAutomatically merge changes (recommended)
OVERWRITE_EXISTINGReplace existing endpoints/schemas completely
KEEP_EXISTINGSkip changes, keep existing
CREATE_NEWCreate new endpoints/schemas (duplicates existing)

Recommendation: Use AUTO_MERGE for intelligent merging without losing existing data.

API Response Format

{ "data": { "counters": { "endpointCreated": 3, "endpointUpdated": 2, "endpointFailed": 0, "endpointIgnored": 0, "schemaCreated": 5, "schemaUpdated": 1, "schemaFailed": 0, "schemaIgnored": 0, "endpointFolderCreated": 1, "endpointFolderUpdated": 0, "schemaFolderCreated": 0, "schemaFolderUpdated": 0 }, "errors": [] } }

Error Handling

Status CodeMeaning
401Token is invalid or expired
404Project ID not found
422OpenAPI spec validation failed

Check data.errors array for detailed error messages.

Workflow

1. Create OpenAPI Spec from Code

Step 1: Analyze existing endpoints

# List all route files find src/routes -name "*.ts" -type f # Read route definitions cat src/routes/user.routes.ts

Step 2: Extract schemas from Zod

// src/schemas/user.schema.ts import { z } from 'zod'; export const createUserSchema = z.object({ emailAddress: z.string().email(), password: z.string().min(8), firstName: z.string(), lastName: z.string() }); // Convert to OpenAPI schema manually or use zod-to-json-schema

Step 3: Build OpenAPI spec

Map routes to OpenAPI paths, schemas to components, camelCase fields.

2. Validate Spec

# Use online validator # https://editor.swagger.io/ # Or use CLI tool npm install -g swagger-cli swagger-cli validate api-spec.yaml

3. Import to Apidog

# Via REST API (automated) ./scripts/import-to-apidog.sh # Or manually in Apidog UI # Import β†’ OpenAPI β†’ Upload file

4. Verify in Apidog

  1. Open Apidog project: https://app.apidog.com/project/{APIDOG_PROJECT_ID}
  2. Check imported endpoints appear in correct folders
  3. Verify schemas are properly structured
  4. Test endpoints with Apidog's testing tools
  5. Update descriptions and add examples

5. Set Endpoint Status

Update x-apidog-status based on implementation progress:

  • designing β†’ developing β†’ testing β†’ released

6. Share with Team

Share Apidog project with team members for:

  • Frontend integration (use mock servers)
  • API testing
  • Documentation review

Automation Script

scripts/import-to-apidog.sh:

#!/bin/bash set -e # Load environment variables source .env # Check required variables if [ -z "$APIDOG_PROJECT_ID" ] || [ -z "$APIDOG_API_TOKEN" ]; then echo "Error: APIDOG_PROJECT_ID and APIDOG_API_TOKEN must be set" exit 1 fi # Generate OpenAPI spec (customize based on your needs) SPEC_FILE="/tmp/api-spec-$(date +%Y%m%d-%H%M%S).json" echo "Generating OpenAPI spec..." # Add your spec generation logic here # For example: ts-node scripts/generate-openapi.ts > $SPEC_FILE # Read spec OPENAPI_SPEC=$(cat $SPEC_FILE | jq -c .) # Import to Apidog echo "Importing to Apidog..." RESPONSE=$(curl -s -X POST \ "https://api.apidog.com/v1/projects/${APIDOG_PROJECT_ID}/import-openapi" \ -H "Authorization: Bearer ${APIDOG_API_TOKEN}" \ -H "X-Apidog-Api-Version: 2024-03-28" \ -H "Content-Type: application/json" \ -d "{ \"input\": ${OPENAPI_SPEC}, \"options\": { \"endpointOverwriteBehavior\": \"AUTO_MERGE\", \"schemaOverwriteBehavior\": \"AUTO_MERGE\" } }") # Parse response ENDPOINT_CREATED=$(echo $RESPONSE | jq -r '.data.counters.endpointCreated') ENDPOINT_UPDATED=$(echo $RESPONSE | jq -r '.data.counters.endpointUpdated') SCHEMA_CREATED=$(echo $RESPONSE | jq -r '.data.counters.schemaCreated') SCHEMA_UPDATED=$(echo $RESPONSE | jq -r '.data.counters.schemaUpdated') ERRORS=$(echo $RESPONSE | jq -r '.data.errors | length') # Display summary echo "" echo "βœ… Import Complete!" echo "" echo "Endpoints:" echo " Created: $ENDPOINT_CREATED" echo " Updated: $ENDPOINT_UPDATED" echo "" echo "Schemas:" echo " Created: $SCHEMA_CREATED" echo " Updated: $SCHEMA_UPDATED" echo "" echo "Errors: $ERRORS" echo "" echo "πŸ”— View in Apidog: https://app.apidog.com/project/${APIDOG_PROJECT_ID}" # Exit with error if there were errors if [ "$ERRORS" != "0" ]; then echo "" echo "⚠️ Import had errors. Check response:" echo $RESPONSE | jq '.data.errors' exit 1 fi

Error Scenarios & Solutions

Missing Environment Variables

Problem: APIDOG_PROJECT_ID or APIDOG_API_TOKEN not set

Solution:

# Add to .env file APIDOG_PROJECT_ID=your-project-id APIDOG_API_TOKEN=your-api-token # Restart application

Schema Conflicts

Problem: New schema conflicts with existing schema

Solution:

  • Use allOf to extend existing schemas
  • Or create with different name
  • Or use OVERWRITE_EXISTING behavior (carefully)

Import Failures

Problem: Automated import fails

Solution:

  • Check API token validity
  • Verify project ID
  • Validate OpenAPI spec syntax
  • Check data.errors in response for details

Invalid OpenAPI Spec

Problem: Generated spec has validation errors

Solution:

# Validate before importing swagger-cli validate api-spec.yaml # Fix validation errors # Common issues: # - Missing required fields # - Invalid $ref paths # - Incorrect enum values # - Wrong data types

Best Practices

1. Schema Reuse

# βœ… CORRECT: Reuse schemas with $ref paths: /users/{userId}: get: responses: '200': content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/User' # ❌ WRONG: Duplicate schema definitions paths: /users/{userId}: get: responses: '200': content: application/json: schema: type: object properties: data: type: object properties: userId: { type: string } # ... duplicated fields

2. Comprehensive Descriptions

# βœ… CORRECT: Clear descriptions paths: /users: post: summary: Create user description: | Creates a new user account with email verification. The password must meet the following requirements: - At least 8 characters - Contains uppercase and lowercase letters - Contains at least one number - Contains at least one special character Upon successful creation, a verification email is sent to the provided email address.

3. Response Examples

responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/User' example: data: userId: "550e8400-e29b-41d4-a716-446655440000" emailAddress: "[email protected]" firstName: "John" lastName: "Doe" isActive: true createdAt: "2025-01-06T12:00:00Z"

4. Security Schemes

components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: JWT access token obtained from /auth/login # Apply globally security: - bearerAuth: [] # Or per endpoint paths: /public/health: get: security: [] # No auth required

5. Version Your API

servers: - url: https://api.example.com/v1 description: Version 1 (current) - url: https://api.example.com/v2 description: Version 2 (beta)

OpenAPI and Apidog integration for Bun.js TypeScript backend. For core patterns, see dev:bunjs. For architecture, see dev:bunjs-architecture.

GitHub Repository
MadAppGang/claude-code
Stars
215
Forks
19
Open Repository
Install Skill
Download ZIP1 files