install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/api-portal-design" ~/.claude/skills/majiayu000-claude-skill-registry-api-portal-design && rm -rf "$T"
manifest:
skills/data/api-portal-design/SKILL.mdsafety · automated scan (medium risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
- makes HTTP requests (curl)
- references .env files
- references API keys
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content
API Portal Design Skill
When to Use This Skill
Use this skill when:
- Api Portal Design tasks - Working on api documentation and developer portal design
- Planning or design - Need guidance on Api Portal Design approaches
- Best practices - Want to follow established patterns and standards
Overview
Design comprehensive API documentation and developer portals for exceptional developer experience.
MANDATORY: Documentation-First Approach
Before designing API portals:
- Invoke
skill for API documentation patternsdocs-management - Verify OpenAPI/AsyncAPI standards via MCP servers (context7)
- Base guidance on industry API documentation best practices
Developer Portal Architecture
Developer Portal Components: ┌─────────────────────────────────────────────────────────────────────────────┐ │ Developer Portal │ ├─────────────────────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Getting │ │ API │ │ Code │ │ API │ │ │ │ Started │ │ Reference │ │ Examples │ │ Console │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ ├─────────────────────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ SDKs & │ │ Change │ │ Status │ │ Support │ │ │ │ Libraries │ │ Log │ │ Page │ │ Center │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ ├─────────────────────────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Authentication & API Keys │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘
Portal Content Structure
Essential Sections
| Section | Purpose | Priority |
|---|---|---|
| Getting Started | First-time user guide | P0 |
| Authentication | How to authenticate | P0 |
| API Reference | Complete endpoint docs | P0 |
| Code Examples | Copy-paste samples | P0 |
| SDKs | Client libraries | P1 |
| Changelog | Version history | P1 |
| Rate Limits | Usage constraints | P1 |
| Errors | Error handling guide | P1 |
| Webhooks | Event notifications | P2 |
| Best Practices | Usage recommendations | P2 |
Getting Started Guide
# Getting Started Get up and running with the [Product] API in 5 minutes. ## Prerequisites - An account on [Product] ([Sign up free](link)) - An API key ([Get your key](link)) - Basic knowledge of REST APIs ## Quick Start ### 1. Get Your API Key 1. Log in to your [Product] dashboard 2. Navigate to **Settings → API Keys** 3. Click **Create New Key** 4. Copy your key (you won't see it again!) ### 2. Make Your First Request ```bash curl -X GET "https://api.example.com/v1/users/me" \ -H "Authorization: Bearer YOUR_API_KEY"
Response:
{ "id": "usr_123abc", "email": "developer@example.com", "name": "Jane Developer", "created_at": "2025-01-15T10:30:00Z" }
3. Explore the API
- API Reference - Complete endpoint documentation
- Code Examples - Ready-to-use samples
- SDKs - Official client libraries
Next Steps
| Goal | Resource |
|---|---|
| Understand authentication | Authentication Guide |
| Browse all endpoints | API Reference |
| Handle errors gracefully | Error Handling |
| Go to production | Production Checklist |
Need Help?
Authentication Documentation
# Authentication All API requests require authentication using Bearer tokens. ## API Keys API keys are long-lived credentials for server-to-server communication. ### Creating API Keys 1. Go to **Dashboard → Settings → API Keys** 2. Click **Create New Key** 3. Give it a descriptive name 4. Select the appropriate permissions 5. Copy and securely store the key ### Using API Keys Include your API key in the `Authorization` header: ```bash curl -X GET "https://api.example.com/v1/resource" \ -H "Authorization: Bearer YOUR_API_KEY"
Key Security Best Practices
| Do | Don't |
|---|---|
| Store keys in environment variables | Commit keys to source control |
| Use separate keys per environment | Share keys between services |
| Rotate keys regularly | Use keys in client-side code |
| Set minimum required permissions | Use admin keys for all operations |
OAuth 2.0
For user-facing applications, use OAuth 2.0 for secure delegated access.
Authorization Code Flow
┌──────────┐ ┌──────────┐ │ Client │ │ Auth │ │ App │ │ Server │ └────┬─────┘ └────┬─────┘ │ │ │ 1. Redirect to authorization endpoint │ │─────────────────────────────────────────►│ │ │ │ 2. User authenticates and consents │ │ │ │ 3. Redirect back with authorization code │ │◄─────────────────────────────────────────│ │ │ │ 4. Exchange code for tokens │ │─────────────────────────────────────────►│ │ │ │ 5. Return access_token and refresh_token │ │◄─────────────────────────────────────────│ │ │
OAuth Endpoints
| Endpoint | URL |
|---|---|
| Authorization | |
| Token | |
| Revoke | |
Scopes
| Scope | Description |
|---|---|
| Read user information |
| Create and update users |
| Read order data |
| Create and modify orders |
Token Refresh
curl -X POST "https://auth.example.com/oauth/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token" \ -d "refresh_token=YOUR_REFRESH_TOKEN" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET"
OpenAPI Specification Template
openapi: 3.1.0 info: title: Product API version: 1.0.0 description: | The Product API provides programmatic access to [Product] features. ## Authentication All endpoints require authentication via Bearer token. Get your API key from the [Dashboard](https://dashboard.example.com). ## Rate Limiting - Standard: 100 requests/minute - Premium: 1000 requests/minute See [Rate Limits](/docs/rate-limits) for details. contact: name: API Support email: api-support@example.com url: https://example.com/support license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: https://api.example.com/v1 description: Production - url: https://api-staging.example.com/v1 description: Staging security: - bearerAuth: [] tags: - name: Users description: User management operations - name: Orders description: Order processing operations paths: /users: get: tags: [Users] operationId: listUsers summary: List all users description: | Returns a paginated list of users in your organization. Results are sorted by creation date, newest first. parameters: - name: limit in: query description: Maximum number of results to return schema: type: integer minimum: 1 maximum: 100 default: 20 - name: cursor in: query description: Pagination cursor from previous response schema: type: string responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/UserList' examples: default: summary: Example response value: data: - id: "usr_123" email: "jane@example.com" name: "Jane Doe" created_at: "2025-01-15T10:30:00Z" has_more: true next_cursor: "cur_abc123" '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/RateLimited' post: tags: [Users] operationId: createUser summary: Create a user description: Creates a new user in your organization. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' examples: basic: summary: Basic user creation value: email: "jane@example.com" name: "Jane Doe" with_metadata: summary: User with metadata value: email: "jane@example.com" name: "Jane Doe" metadata: department: "Engineering" role: "Developer" responses: '201': description: User created content: application/json: schema: $ref: '#/components/schemas/User' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '409': description: User already exists content: application/json: schema: $ref: '#/components/schemas/Error' /users/{userId}: get: tags: [Users] operationId: getUser summary: Get a user description: Retrieves a user by their ID. parameters: - name: userId in: path required: true description: The user's unique identifier schema: type: string pattern: '^usr_[a-zA-Z0-9]+$' example: usr_123abc responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/User' '404': $ref: '#/components/responses/NotFound' components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: | Use your API key as the Bearer token. Example: `Authorization: Bearer sk_live_abc123` schemas: User: type: object required: [id, email, created_at] properties: id: type: string description: Unique identifier for the user example: usr_123abc email: type: string format: email description: User's email address example: jane@example.com name: type: string description: User's display name example: Jane Doe created_at: type: string format: date-time description: When the user was created example: "2025-01-15T10:30:00Z" metadata: type: object additionalProperties: true description: Custom key-value pairs UserList: type: object properties: data: type: array items: $ref: '#/components/schemas/User' has_more: type: boolean description: Whether more results are available next_cursor: type: string description: Cursor for fetching next page CreateUserRequest: type: object required: [email] properties: email: type: string format: email name: type: string metadata: type: object additionalProperties: true Error: type: object required: [error] properties: error: type: object required: [code, message] properties: code: type: string description: Error code example: invalid_request message: type: string description: Human-readable error message example: The email field is required details: type: array items: type: object properties: field: type: string message: type: string responses: BadRequest: description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: invalid_request message: Validation failed details: - field: email message: Invalid email format Unauthorized: description: Authentication required content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: unauthorized message: Invalid or missing API key NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: not_found message: User not found RateLimited: description: Rate limit exceeded headers: X-RateLimit-Limit: schema: type: integer description: Request limit per minute X-RateLimit-Remaining: schema: type: integer description: Remaining requests in current window X-RateLimit-Reset: schema: type: integer description: Unix timestamp when limit resets content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: rate_limited message: Too many requests. Please retry after 60 seconds.
Error Documentation
# Error Handling The API uses conventional HTTP response codes and returns detailed error information. ## HTTP Status Codes | Code | Meaning | |------|---------| | 200 | Success | | 201 | Created | | 204 | No Content | | 400 | Bad Request - Invalid parameters | | 401 | Unauthorized - Invalid or missing credentials | | 403 | Forbidden - Insufficient permissions | | 404 | Not Found - Resource doesn't exist | | 409 | Conflict - Resource already exists | | 422 | Unprocessable - Validation failed | | 429 | Too Many Requests - Rate limited | | 500 | Internal Error - Server-side issue | ## Error Response Format ```json { "error": { "code": "invalid_request", "message": "The email field is required", "request_id": "req_abc123", "details": [ { "field": "email", "message": "This field is required" } ] } }
Error Codes Reference
Authentication Errors
| Code | Description | Resolution |
|---|---|---|
| Missing or invalid API key | Check your API key is correct |
| Access token has expired | Refresh your token |
| Token lacks required scope | Request additional scopes |
Validation Errors
| Code | Description | Resolution |
|---|---|---|
| Request body is malformed | Check JSON syntax |
| One or more fields invalid | See array |
| Required field not provided | Include all required fields |
Resource Errors
| Code | Description | Resolution |
|---|---|---|
| Resource doesn't exist | Verify the ID is correct |
| Resource already exists | Use existing resource or change identifier |
| Resource is being modified | Retry after a short delay |
Handling Errors in Code
csharp
try { var user = await client.Users.GetAsync(userId, ct); } catch (ApiException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { _logger.LogWarning("User {UserId} not found", userId); return NotFound(); } catch (ApiException ex) when (ex.StatusCode == HttpStatusCode.TooManyRequests) { var retryAfter = ex.Headers.RetryAfter?.Delta ?? TimeSpan.FromSeconds(60); await Task.Delay(retryAfter, ct); // Retry request } catch (ApiException ex) { _logger.LogError(ex, "API error: {Code} - {Message}", ex.Error.Code, ex.Error.Message); throw; }
TypeScript
try { const user = await client.users.get(userId); } catch (error) { if (error instanceof ApiError) { switch (error.code) { case 'not_found': console.warn(`User ${userId} not found`); return null; case 'rate_limited': await sleep(error.retryAfter ?? 60000); return client.users.get(userId); // Retry default: console.error(`API error: ${error.code} - ${error.message}`); throw error; } } throw error; }
Code Examples Section
# Code Examples Ready-to-use examples in popular languages. ## Create a User ### cURL ```bash curl -X POST "https://api.example.com/v1/users" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "email": "jane@example.com", "name": "Jane Doe" }'
C# (.NET)
using var client = new ProductApiClient(apiKey); var user = await client.Users.CreateAsync(new CreateUserRequest { Email = "jane@example.com", Name = "Jane Doe" }); Console.WriteLine($"Created user: {user.Id}");
TypeScript
import { ProductApi } from '@example/sdk'; const client = new ProductApi({ apiKey: process.env.API_KEY }); const user = await client.users.create({ email: 'jane@example.com', name: 'Jane Doe', }); console.log(`Created user: ${user.id}`);
Python
from example_sdk import ProductApi client = ProductApi(api_key=os.environ["API_KEY"]) user = client.users.create( email="jane@example.com", name="Jane Doe" ) print(f"Created user: {user.id}")
Portal Tooling Options
| Tool | Type | Best For |
|---|---|---|
| Stoplight | Hosted | Design-first, collaboration |
| Redocly | Hosted/Self | OpenAPI rendering |
| ReadMe | Hosted | Full portal, interactive |
| SwaggerHub | Hosted | Swagger ecosystem |
| Scalar | Open Source | Modern, customizable |
| Docusaurus + Plugin | Open Source | Full control |
Best Practices
Developer Experience Principles
| Principle | Implementation |
|---|---|
| Time to First Call | Minimize steps to make first API call |
| Copy-Paste Ready | All examples should work immediately |
| Error Messages | Clear, actionable error responses |
| Consistency | Same patterns across all endpoints |
| Discoverability | Easy to find and navigate |
Documentation Quality Checklist
- Every endpoint has description and examples
- All parameters documented with types and constraints
- Response schemas fully documented
- Error codes explained with resolutions
- Authentication clearly explained
- Rate limits documented
- Code examples in multiple languages
- Getting started guide under 5 minutes
Workflow
When designing API portals:
- Define Audience: Who will use the API?
- Structure Content: Organize by user journey
- Write OpenAPI Spec: Complete specification
- Add Examples: Working code in target languages
- Build Portal: Choose tooling, implement
- Test with Users: Validate time-to-first-call
- Iterate: Improve based on feedback
References
For detailed guidance:
Last Updated: 2025-12-26