Marketplace API Documentation
Complete API reference for all marketplace endpoints in the ATOM SaaS platform.
Table of Contents
- Overview
- Authentication
- Skill Marketplace
- Agent Marketplace
- Domain Marketplace
- Canvas Component Marketplace
- Workflow Marketplace
- Private Marketplace
- Error Codes
---
Overview
The marketplace system provides multiple marketplaces for different types of assets:
- **Skill Marketplace**: Share and discover agent skills
- **Agent Marketplace**: Publish and install agent templates
- **Domain Marketplace**: Share specialist domains
- **Canvas Component Marketplace**: UI components and canvases
- **Workflow Marketplace**: Workflow templates and blueprints
- **Private Marketplace**: Tenant-specific skill management
All marketplace endpoints support:
- Search and filtering
- Rating and reviews
- Version management
- Approval workflows
- Installation tracking
---
Authentication
Most marketplace endpoints require authentication. The platform supports multiple authentication methods:
API Key Authentication
X-API-Key: your-api-key-hereOAuth Bearer Token
Authorization: Bearer your-access-tokenSession Authentication
For web-based requests, session cookies are automatically handled.
---
Skill Marketplace
Base URL: /api/skills
Browse Marketplace
GET /api/skills/marketplaceBrowse and search for skills in the marketplace.
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| query | string | No | - | Search term |
| category | string | No | - | Filter by category |
| tags | string | No | - | Comma-separated tags |
| skill_type | string | No | - | Filter by type (api, function, script, docker, container) |
| sort_by | string | No | popularity | Sort field |
| limit | integer | No | 50 | Max results |
| offset | integer | No | 0 | Pagination offset |
**Response:**
{
"success": true,
"skills": [
{
"id": "skill-uuid-123",
"name": "Data Analysis Skill",
"description": "Advanced data analysis with Python",
"category": "productivity",
"skill_type": "script",
"price": 0.0,
"rating": 4.5,
"rating_count": 42,
"installs": 156,
"tags": ["python", "data", "analysis"],
"is_approved": true,
"created_at": "2026-04-01T12:00:00Z"
}
]
}**Authentication:** Required (SKILL_VIEW permission)
---
Publish Skill
POST /api/skills/publishPublish a private skill to the marketplace.
**Request Body:**
{
"skill_id": "skill-uuid-123",
"price": 0.0,
"category": "productivity",
"tags": ["python", "data"],
"long_description": "Full description here...",
"documentation_url": "https://docs.example.com/skill"
}**Response:**
{
"success": true,
"marketplace_id": "marketplace-uuid-456",
"status": "pending_approval",
"message": "Skill submitted for marketplace review"
}**Authentication:** Required (SKILL_MANAGE permission)
---
Approve Skill (Admin)
POST /api/skills/approve/{marketplace_id}Approve a skill for marketplace availability.
**Path Parameters:**
marketplace_id(string): Marketplace listing ID
**Response:**
{
"success": true,
"marketplace_id": "marketplace-uuid-456",
"status": "approved",
"approved_at": "2026-04-05T12:00:00Z"
}**Authentication:** Required (GOVERNANCE_APPROVE permission)
---
Reject Skill (Admin)
POST /api/skills/reject/{marketplace_id}Reject a marketplace submission.
**Path Parameters:**
marketplace_id(string): Marketplace listing ID
**Query Parameters:**
reason(string): Rejection reason
**Response:**
{
"success": true,
"marketplace_id": "marketplace-uuid-456",
"status": "rejected",
"reason": "Does not meet quality standards"
}**Authentication:** Required (GOVERNANCE_APPROVE permission)
---
Install Skill
POST /api/skills/installInstall a marketplace skill into your tenant.
**Request Body:**
{
"skill_id": "marketplace-uuid-456",
"agent_id": "agent-uuid-789",
"config_overrides": {
"timeout": 30
}
}**Response:**
{
"success": true,
"skill_id": "installed-skill-uuid-999",
"status": "installed",
"message": "Skill installed successfully"
}**Authentication:** Required (SKILL_MANAGE permission)
---
Rate Skill
POST /api/skills/rate/{marketplace_id}Rate and review a marketplace skill.
**Path Parameters:**
marketplace_id(string): Marketplace listing ID
**Request Body:**
{
"rating": 5,
"review": "Excellent skill, saved me hours of work!"
}**Response:**
{
"success": true,
"rating": 5,
"new_average": 4.7,
"total_ratings": 43
}**Authentication:** Required (SKILL_VIEW permission)
---
Create Skill Version
POST /api/skills/versionCreate a frozen version of a skill.
**Query Parameters:**
skill_id(string): Skill IDversion_name(string): Version name (e.g., "v1.0.0")description(string): Optional description
**Response:**
{
"success": true,
"version_id": "version-uuid-123",
"version_name": "v1.0.0"
}**Authentication:** Required (SKILL_MANAGE permission)
---
Get Version History
GET /api/skills/history/{skill_id}Get the version history for a skill.
**Path Parameters:**
skill_id(string): Skill ID
**Response:**
{
"success": true,
"history": [
{
"version_id": "version-uuid-123",
"version_name": "v1.0.0",
"description": "Initial release",
"created_at": "2026-04-01T12:00:00Z"
}
]
}**Authentication:** Required (SKILL_VIEW permission)
---
Rollback Skill
POST /api/skills/rollback/{skill_id}Rollback a skill to a previous version.
**Path Parameters:**
skill_id(string): Skill ID
**Query Parameters:**
version_id(string): Target version ID
**Response:**
{
"success": true,
"message": "Skill skill-uuid-123 rolled back to version version-uuid-456"
}**Authentication:** Required (SKILL_MANAGE permission)
---
Agent Marketplace
Base URL: /api/agent-marketplace
Browse Agents
GET /api/agent-marketplace/browseBrowse available agent templates.
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | integer | No | 50 | Max results |
| offset | integer | No | 0 | Pagination offset |
**Response:**
{
"agents": [
{
"id": "agent-template-uuid-123",
"name": "Sales Assistant",
"description": "Automated sales follow-up agent",
"category": "sales",
"price": 19.99,
"rating": 4.8,
"installs": 234,
"version": "1.2.0"
}
],
"total": 150,
"limit": 50,
"offset": 0
}**Authentication:** Required (Session auth)
---
Publish Agent
POST /api/agent-marketplace/publish/{agent_id}Publish an agent to the marketplace.
**Path Parameters:**
agent_id(string): Agent ID to publish
**Query Parameters:**
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Agent name |
| description | string | Yes | Agent description |
| price | float | No | Price (default: 0.0) |
| category | string | No | Category |
**Response:**
{
"success": true,
"template_id": "agent-template-uuid-456",
"status": "pending_approval",
"message": "Agent submitted for marketplace review"
}**Authentication:** Required (Session auth)
---
Install Agent
POST /api/agent-marketplace/install/{template_id}Install an agent template from the marketplace.
**Path Parameters:**
template_id(string): Template ID to install
**Response:**
{
"success": true,
"agent_id": "installed-agent-uuid-789",
"status": "installed",
"message": "Agent installed successfully"
}**Authentication:** Required (Session auth)
---
Domain Marketplace
Base URL: /api/v1/domains/marketplace
Submit Domain
POST /api/v1/domains/marketplace/submitSubmit a domain to the marketplace.
**Request Body:**
{
"domain_id": "domain-uuid-123",
"price_usd": 29.99,
"license_type": "MIT",
"tags": ["sales", "crm", "automation"]
}**Response:**
{
"success": true,
"domain_id": "domain-uuid-123",
"status": "pending_approval",
"price_usd": 29.99,
"license_type": "MIT"
}**Authentication:** Required (Tenant context)
---
List My Submissions
GET /api/v1/domains/marketplace/my-submissionsList domains submitted by current tenant.
**Response:**
[
{
"domain_id": "domain-uuid-123",
"domain_name": "Sales Automation",
"status": "approved",
"price_usd": 29.99,
"install_count": 45,
"rating_average": 4.7
}
]**Authentication:** Required (Tenant context)
---
Approve Domain (Admin)
POST /api/v1/domains/marketplace/{domain_id}/approveApprove a domain for marketplace.
**Path Parameters:**
domain_id(string): Domain ID
**Response:**
{
"success": true,
"domain_id": "domain-uuid-123",
"status": "approved"
}**Authentication:** Required (Tenant context, TODO: Admin check)
---
Reject Domain (Admin)
POST /api/v1/domains/marketplace/{domain_id}/rejectReject a domain submission.
**Path Parameters:**
domain_id(string): Domain ID
**Query Parameters:**
reason(string): Rejection reason
**Response:**
{
"success": true,
"domain_id": "domain-uuid-123",
"status": "rejected",
"reason": "Does not meet quality standards"
}**Authentication:** Required (Tenant context, TODO: Admin check)
---
Search Marketplace
GET /api/v1/domains/marketplace/searchSearch marketplace for domains.
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| q | string | No | - | Search query |
| category | string | No | - | Filter by category |
| tags | string | No | - | Comma-separated tags |
| max_price | float | No | - | Maximum price |
| limit | integer | No | 20 | Max results (1-100) |
**Response:**
[
{
"id": "domain-uuid-123",
"domain_name": "Sales Automation",
"domain_slug": "sales-automation",
"description": "Advanced sales workflows",
"category": "sales",
"price_usd": 29.99,
"license_type": "MIT",
"tags": ["sales", "crm", "automation"],
"install_count": 45,
"rating_average": 4.7,
"rating_count": 12,
"publisher_tenant_id": "tenant-uuid-789"
}
]**Authentication:** None required
---
Get Trending Domains
GET /api/v1/domains/marketplace/trendingGet trending domains by install count.
**Query Parameters:**
limit(integer): Max results (1-50, default: 10)
**Response:**
[
{
"id": "domain-uuid-123",
"domain_name": "Sales Automation",
"install_count": 156,
"rating_average": 4.7
}
]**Authentication:** None required
---
Get Marketplace Stats
GET /api/v1/domains/marketplace/statsGet marketplace statistics.
**Response:**
{
"total_domains": 234,
"approved_domains": 189,
"pending_domains": 45,
"total_installs": 5678
}**Authentication:** None required
---
Install Domain
POST /api/v1/domains/marketplace/installInstall a domain template from marketplace.
**Request Body:**
{
"template_domain_id": "domain-uuid-123",
"custom_name": "My Sales Domain"
}**Response:**
{
"success": true,
"domain_id": "installed-domain-uuid-456",
"domain_name": "My Sales Domain",
"template_id": "domain-uuid-123"
}**Authentication:** Required (Tenant context)
---
Rate Domain
POST /api/v1/domains/marketplace/{domain_id}/rateRate a domain in the marketplace.
**Path Parameters:**
domain_id(string): Domain ID
**Request Body:**
{
"rating": 4.5
}**Response:**
{
"success": true,
"domain_id": "domain-uuid-123",
"rating": 4.5,
"new_average": 4.6,
"total_ratings": 13
}**Authentication:** Required (Tenant context)
---
Get Domain Details
GET /api/v1/domains/marketplace/{domain_id}Get detailed information about a marketplace domain.
**Path Parameters:**
domain_id(string): Domain ID
**Response:**
{
"id": "domain-uuid-123",
"domain_name": "Sales Automation",
"domain_slug": "sales-automation",
"description": "Advanced sales workflows",
"category": "sales",
"price_usd": 29.99,
"license_type": "MIT",
"tags": ["sales", "crm", "automation"],
"install_count": 45,
"rating_average": 4.7,
"rating_count": 12,
"publisher_tenant_id": "tenant-uuid-789"
}**Authentication:** None required
---
Canvas Component Marketplace
Base URL: /api/components (legacy) or /api/canvas-marketplace (preferred)
Browse Components
GET /api/canvas-marketplace/componentsBrowse marketplace components.
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| query | string | No | - | Search query |
| category | string | No | - | Filter by category |
| tags | string | No | - | Comma-separated tags |
| component_type | string | No | - | Filter by type |
| min_price | float | No | - | Minimum price |
| max_price | float | No | - | Maximum price |
| is_free | boolean | No | false | Free only |
| is_featured | boolean | No | false | Featured only |
| sort_by | string | No | created_at | Sort field |
| sort_order | string | No | desc | Sort order (asc/desc) |
| limit | integer | No | 50 | Max results (max 100) |
| offset | integer | No | 0 | Pagination offset |
**Response:**
{
"components": [
{
"id": "component-uuid-123",
"name": "Data Table",
"description": "Interactive data table component",
"category": "ui",
"component_type": "component",
"tags": ["table", "data", "ui"],
"version": "1.0.0",
"thumbnail_url": "https://cdn.example.com/thumb.png",
"price": 0.0,
"is_free": true,
"is_featured": true,
"license": "MIT",
"installs": 234,
"rating": 4.7,
"rating_count": 45,
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-05T12:00:00Z"
}
],
"total": 150,
"limit": 50,
"offset": 0,
"has_more": true
}**Authentication:** None required (optional for rate limits)
---
Get Component Details
GET /api/canvas-marketplace/components/{component_id}Get detailed component information including code and config.
**Path Parameters:**
component_id(string): Component ID
**Response:**
{
"id": "component-uuid-123",
"name": "Data Table",
"description": "Interactive data table component",
"category": "ui",
"component_type": "component",
"tags": ["table", "data", "ui"],
"version": "1.0.0",
"code": "export function DataTable({ data }) { ... }",
"config_schema": {
"type": "object",
"properties": {
"data": { "type": "array" }
}
},
"dependencies": ["react", "lodash"],
"css_dependencies": ["bootstrap"],
"thumbnail_url": "https://cdn.example.com/thumb.png",
"preview_url": "https://cdn.example.com/preview.png",
"demo_url": "https://demo.example.com",
"price": 0.0,
"is_free": true,
"is_featured": true,
"license": "MIT",
"installs": 234,
"rating": 4.7,
"rating_count": 45,
"recent_ratings": [
{
"id": "rating-uuid-456",
"rating": 5,
"review": "Great component!",
"helpful_count": 12,
"created_at": "2026-04-05T12:00:00Z"
}
],
"created_at": "2026-04-01T12:00:00Z",
"updated_at": "2026-04-05T12:00:00Z"
}**Authentication:** None required
---
Publish Component
POST /api/canvas-marketplace/components/publishSubmit a component for marketplace review.
**Request Body:**
{
"component_id": "component-uuid-123",
"price": 0.0,
"license": "MIT",
"tags": ["table", "data", "ui"]
}**Response:**
{
"status": "submitted_for_approval",
"component_id": "component-uuid-123",
"message": "Component submitted for marketplace review. You will be notified once approved."
}**Authentication:** Required (Session auth)
---
Approve Component (Admin)
POST /api/canvas-marketplace/components/{component_id}/approveApprove a component for the marketplace.
**Path Parameters:**
component_id(string): Component ID
**Response:**
{
"status": "approved",
"component_id": "component-uuid-123"
}**Authentication:** Required (SUPER_ADMIN, ADMIN, or OWNER role)
---
Reject Component (Admin)
POST /api/canvas-marketplace/components/{component_id}/rejectReject a component from the marketplace.
**Path Parameters:**
component_id(string): Component ID
**Query Parameters:**
reason(string): Rejection reason
**Response:**
{
"status": "rejected",
"component_id": "component-uuid-123",
"reason": "Does not meet quality standards"
}**Authentication:** Required (SUPER_ADMIN, ADMIN, or OWNER role)
---
Install Component
POST /api/canvas-marketplace/components/installInstall a marketplace component to tenant's canvas.
**Request Body:**
{
"component_id": "component-uuid-123",
"canvas_id": "canvas-uuid-456"
}**Response:**
{
"status": "installed",
"component_id": "component-uuid-123",
"canvas_id": "canvas-uuid-456",
"message": "Component installed successfully"
}**Authentication:** Required (Session auth)
---
Rate Component
POST /api/canvas-marketplace/components/{component_id}/rateRate and review a marketplace component.
**Path Parameters:**
component_id(string): Component ID
**Request Body:**
{
"rating": 5,
"review": "Excellent component!"
}**Response:**
{
"status": "rated",
"component_id": "component-uuid-123",
"rating": 5,
"aggregate_rating": 4.7
}**Authentication:** Required (Session auth)
---
Get Component Ratings
GET /api/canvas-marketplace/components/{component_id}/ratingsGet ratings and reviews for a component.
**Path Parameters:**
component_id(string): Component ID
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | integer | No | 20 | Max ratings (max 100) |
| offset | integer | No | 0 | Pagination offset |
**Response:**
{
"ratings": [
{
"id": "rating-uuid-456",
"rating": 5,
"review": "Great component!",
"helpful_count": 12,
"not_helpful_count": 0,
"author_response": "Thank you!",
"author_response_at": "2026-04-06T12:00:00Z",
"created_at": "2026-04-05T12:00:00Z"
}
],
"total": 45,
"limit": 20,
"offset": 0
}**Authentication:** None required
---
List Categories
GET /api/canvas-marketplace/categoriesList all component categories with counts.
**Response:**
{
"categories": [
{
"name": "ui",
"count": 45
},
{
"name": "charts",
"count": 23
}
]
}**Authentication:** None required
---
List Tags
GET /api/canvas-marketplace/tagsList all popular tags.
**Response:**
{
"tags": [
{
"name": "table",
"count": 42
},
{
"name": "data",
"count": 35
}
]
}**Authentication:** None required
---
Workflow Marketplace
Base URL: /api/marketplace
Get Templates
GET /api/marketplace/templatesGet workflow templates with filtering.
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| category | string | No | - | Filter by category |
| template_type | string | No | - | Filter by type (legacy, advanced, industry) |
| industry | string | No | - | Filter by industry |
| tags | list | No | - | Filter by tags |
**Response:**
[
{
"id": "tmpl_email_summarizer",
"name": "Daily Email Summarizer",
"description": "Summarize unread emails from Gmail and send digest to Slack",
"category": "Productivity",
"author": "ATOM Team",
"version": "1.0.0",
"integrations": ["gmail", "slack", "openai"],
"complexity": "Beginner",
"tags": ["email", "automation"],
"estimated_duration": 300,
"multi_step_support": true,
"pause_resume_support": false,
"downloads": 156,
"rating": 4.5,
"template_type": "legacy",
"created_at": "2026-04-01T12:00:00Z"
}
]**Authentication:** None required
---
Get Template Types
GET /api/marketplace/templates/typesGet available template types.
**Response:**
{
"template_types": [
{
"value": "legacy",
"label": "Legacy",
"description": "Legacy workflow templates"
},
{
"value": "advanced",
"label": "Advanced",
"description": "Advanced workflow templates"
},
{
"value": "industry",
"label": "Industry",
"description": "Industry workflow templates"
}
]
}**Authentication:** None required
---
Get Featured Templates
GET /api/marketplace/templates/featuredGet featured templates.
**Query Parameters:**
limit(integer): Max results (1-50, default: 10)
**Response:**
[
{
"id": "tmpl_email_summarizer",
"name": "Daily Email Summarizer",
"rating": 4.5,
"downloads": 156,
"is_featured": true
}
]**Authentication:** None required
---
Get Template Details
GET /api/marketplace/templates/{template_id}Get a specific template by ID.
**Path Parameters:**
template_id(string): Template ID
**Response:**
{
"id": "tmpl_email_summarizer",
"name": "Daily Email Summarizer",
"description": "Summarize unread emails from Gmail",
"category": "Productivity",
"author": "ATOM Team",
"version": "1.0.0",
"integrations": ["gmail", "slack", "openai"],
"complexity": "Beginner",
"workflow_data": {
"nodes": [
{
"id": "1",
"type": "trigger",
"label": "Every Morning",
"config": {"cron": "0 9 * * *"}
}
],
"edges": [
{"source": "1", "target": "2"}
]
},
"downloads": 156,
"rating": 4.5,
"tags": ["email", "automation"]
}**Authentication:** None required
---
Import Template
POST /api/marketplace/templates/{template_id}/importImport a template into your workspace.
**Path Parameters:**
template_id(string): Template ID
**Response:**
{
"id": "workflow-uuid-789",
"name": "Imported: Daily Email Summarizer",
"nodes": [...],
"edges": [...],
"imported_at": "2026-04-05T12:00:00Z"
}**Authentication:** None required
---
Create Advanced Template
POST /api/marketplace/templates/advancedCreate a new advanced workflow template.
**Request Body:**
{
"id": "advanced_custom_workflow",
"name": "Custom Advanced Workflow",
"description": "My custom workflow",
"category": "Custom",
"author": "Your Name",
"version": "1.0.0",
"integrations": ["slack", "email"],
"complexity": "Intermediate",
"tags": ["custom", "automation"],
"input_schema": [
{
"name": "data_source",
"type": "select",
"label": "Data Source",
"required": true
}
],
"steps": [
{
"step_id": "validate",
"name": "Validate Inputs",
"step_type": "validation",
"estimated_duration": 30
}
],
"estimated_duration": 300,
"prerequisites": ["api_access"],
"use_cases": ["Data processing"],
"benefits": ["Automation", "Efficiency"]
}**Response:**
{
"id": "advanced_custom_workflow",
"name": "Custom Advanced Workflow",
"input_schema": [...],
"steps": [...],
"estimated_duration": 300,
"created_at": "2026-04-05T12:00:00Z"
}**Authentication:** None required
---
Create Workflow from Template
POST /api/marketplace/templates/{template_id}/create-workflowCreate a workflow from an advanced template.
**Path Parameters:**
template_id(string): Template ID
**Query Parameters:**
workflow_name(string): Workflow nameparameters(object): User inputs (JSON)
**Response:**
{
"status": "success",
"workflow_definition": {
"workflow_id": "workflow-uuid-789",
"name": "My Workflow",
"category": "Data Processing",
"input_schema": [...],
"steps": [...],
"user_inputs": {...}
},
"message": "Workflow 'My Workflow' created successfully from template tmpl_email_summarizer"
}**Authentication:** None required
---
Import Workflow (File)
POST /api/marketplace/importImport a workflow from a JSON file.
**Request Body (multipart/form-data):**
file: Workflow JSON file
**Response:**
{
"id": "workflow-uuid-789",
"name": "Imported: My Workflow",
"nodes": [...],
"edges": [...],
"imported_at": "2026-04-05T12:00:00Z"
}**Authentication:** None required
---
Export Workflow
POST /api/marketplace/exportExport a workflow to JSON format.
**Request Body:**
{
"name": "My Workflow",
"description": "My custom workflow",
"nodes": [...],
"edges": [...]
}**Response:**
{
"name": "My Workflow",
"description": "My custom workflow",
"nodes": [...],
"edges": [...],
"metadata": {
"exported_at": "2026-04-05T12:00:00Z",
"version": "1.0.0"
}
}**Authentication:** None required
---
Get Template Statistics
GET /api/marketplace/templates/statisticsGet marketplace statistics.
**Response:**
{
"total_templates": 50,
"total_downloads": 1234,
"average_rating": 4.5,
"categories": {
"Productivity": {"count": 20, "downloads": 500},
"Sales": {"count": 15, "downloads": 400}
},
"template_types": {
"legacy": {"count": 30, "downloads": 600},
"advanced": {"count": 15, "downloads": 500},
"industry": {"count": 5, "downloads": 134}
},
"complexity_levels": {
"Beginner": {"count": 20, "downloads": 400},
"Intermediate": {"count": 20, "downloads": 500},
"Advanced": {"count": 10, "downloads": 334}
}
}**Authentication:** None required
---
Private Marketplace
Base URL: /api/v1/skills
List Private Skills
GET /api/v1/skills/privateList tenant's private skills (created + installed).
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| query | string | No | - | Search term |
| category | string | No | - | Filter by category |
| skill_type | string | No | - | Filter by type |
| is_installed | boolean | No | - | Filter by installation status |
| sort_by | string | No | name | Sort field |
| sort_order | string | No | asc | Sort order (asc/desc) |
| limit | integer | No | 50 | Max results |
| offset | integer | No | 0 | Pagination offset |
**Response:**
{
"success": true,
"skills": [
{
"id": "skill-uuid-123",
"name": "My Custom Skill",
"description": "Custom skill for my workflow",
"skill_type": "function",
"category": "productivity",
"is_own": true,
"is_installed": false,
"rating": 4.5,
"created_at": "2026-04-01T12:00:00Z"
}
],
"total": 25,
"limit": 50,
"offset": 0
}**Authentication:** Required (SKILL_VIEW permission)
---
Install from Marketplace
POST /api/v1/skills/private/installInstall a marketplace skill to private marketplace.
**Request Body:**
{
"marketplace_skill_id": "marketplace-skill-uuid-123",
"agent_id": "agent-uuid-456",
"config_overrides": {
"timeout": 60
}
}**Response:**
{
"success": true,
"skill_id": "installed-skill-uuid-789",
"status": "installed",
"message": "Skill installed successfully",
"packages_installed": [
{
"package_name": "requests",
"package_type": "python",
"status": "installed"
}
]
}**Authentication:** Required (SKILL_MANAGE permission)
---
Customize Skill
PUT /api/v1/skills/private/{skill_id}Customize an installed private skill.
**Path Parameters:**
skill_id(string): Skill ID
**Request Body:**
{
"name": "My Custom Name",
"description": "My custom description",
"config_overrides": {
"timeout": 60
},
"environment_vars": {
"API_KEY": "custom-key"
}
}**Response:**
{
"success": true,
"skill_id": "skill-uuid-123",
"name": "My Custom Name",
"description": "My custom description",
"config_overrides_applied": true
}**Authentication:** Required (SKILL_MANAGE permission)
---
Uninstall Skill
DELETE /api/v1/skills/private/{skill_id}Uninstall a marketplace skill from private marketplace.
**Path Parameters:**
skill_id(string): Skill ID
**Response:**
{
"success": true,
"skill_id": "skill-uuid-123",
"status": "uninstalled",
"message": "Skill uninstalled successfully"
}**Authentication:** Required (SKILL_MANAGE permission)
---
Create Private Skill
POST /api/v1/skills/privateCreate a completely private skill (not shared to marketplace).
**Request Body:**
{
"name": "My Private Skill",
"description": "Internal skill only",
"skill_type": "function",
"input_schema": {
"type": "object",
"properties": {
"data": {"type": "string"}
}
},
"output_schema": {
"type": "object",
"properties": {
"result": {"type": "string"}
}
},
"config": {
"timeout": 30
},
"code": "def execute(data): return {'result': data}",
"category": "productivity",
"tags": ["internal", "custom"]
}**Response:**
{
"success": true,
"skill_id": "skill-uuid-123",
"name": "My Private Skill",
"status": "created",
"is_public": false
}**Authentication:** Required (SKILL_MANAGE permission)
---
Public Marketplace API
Base URL: /api/public/v1/marketplace
Browse Public Skills
GET /api/public/v1/marketplace/skillsBrowse the public skill marketplace (read-only API).
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| query | string | No | - | Search term |
| category | string | No | - | Filter by category |
| tags | string | No | - | Comma-separated tags |
| skill_type | string | No | - | Filter by type |
| is_free | boolean | No | false | Free only |
| is_featured | boolean | No | false | Featured only |
| sort_by | string | No | created_at | Sort field |
| sort_order | string | No | desc | Sort order (asc/desc) |
| limit | integer | No | 50 | Max results (max 100) |
| offset | integer | No | 0 | Pagination offset |
**Response:**
{
"skills": [
{
"id": "skill-uuid-123",
"name": "Data Analysis",
"description": "Advanced data analysis",
"category": "productivity",
"skill_type": "script",
"price": 0.0,
"is_free": true,
"rating": 4.5,
"rating_count": 42,
"installs": 156,
"tags": ["python", "data"],
"created_at": "2026-04-01T12:00:00Z"
}
],
"total": 150,
"limit": 50,
"offset": 0,
"has_more": true
}**Authentication:** Optional (higher rate limits with auth)
---
Get Public Skill Details
GET /api/public/v1/marketplace/skills/{skill_id}Get detailed information about a specific marketplace skill.
**Path Parameters:**
skill_id(string): Skill ID
**Response:**
{
"id": "skill-uuid-123",
"name": "Data Analysis",
"description": "Advanced data analysis with Python",
"long_description": "Full documentation...",
"category": "productivity",
"skill_type": "script",
"input_schema": {...},
"output_schema": {...},
"config": {...},
"price": 0.0,
"is_free": true,
"rating": 4.5,
"rating_count": 42,
"installs": 156,
"tags": ["python", "data"],
"license": "MIT",
"documentation_url": "https://docs.example.com",
"repository_url": "https://github.com/example/skill",
"python_packages": [{"name": "pandas", "version": "2.0.0"}],
"npm_packages": [],
"recent_reviews": [
{
"rating": 5,
"review": "Excellent!",
"created_at": "2026-04-05T12:00:00Z"
}
],
"created_at": "2026-04-01T12:00:00Z"
}**Authentication:** Optional
---
Get Categories
GET /api/public/v1/marketplace/categoriesGet all skill categories.
**Response:**
{
"categories": ["productivity", "sales", "finance", "communication"]
}**Authentication:** Optional
---
Get Tags
GET /api/public/v1/marketplace/tagsGet all skill tags with usage counts.
**Response:**
{
"tags": [
{"name": "python", "count": 42},
{"name": "api", "count": 35},
{"name": "data", "count": 28}
]
}**Authentication:** Optional
---
Submit Skill (Public API)
POST /api/public/v1/marketplace/submitSubmit a skill for the marketplace (requires authentication).
**Request Body:**
{
"name": "My Skill",
"description": "Skill description",
"skill_type": "function",
"input_schema": {...},
"output_schema": {...},
"config": {...},
"code": "...",
"long_description": "Full documentation...",
"category": "productivity",
"tags": ["python", "data"],
"price": 0.0,
"license": "MIT",
"documentation_url": "https://docs.example.com",
"repository_url": "https://github.com/example/skill",
"python_packages": [{"name": "requests", "version": "2.28.0"}],
"npm_packages": []
}**Response:**
{
"success": true,
"skill_id": "skill-uuid-123",
"status": "pending_approval",
"message": "Skill submitted for marketplace review"
}**Authentication:** Required (API key or OAuth token)
---
Rate Skill (Public API)
POST /api/public/v1/marketplace/skills/{skill_id}/rateRate a marketplace skill (requires authentication).
**Path Parameters:**
skill_id(string): Skill ID
**Request Body:**
{
"rating": 5,
"review": "Excellent skill!"
}**Response:**
{
"success": true,
"rating": 5,
"new_average": 4.7,
"total_ratings": 43
}**Authentication:** Required (API key or OAuth token)
---
Get Reviews
GET /api/public/v1/marketplace/skills/{skill_id}/reviewsGet reviews for a skill (no authentication required).
**Path Parameters:**
skill_id(string): Skill ID
**Query Parameters:**
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | integer | No | 20 | Max reviews (1-100) |
| offset | integer | No | 0 | Pagination offset |
**Response:**
{
"reviews": [
{
"id": "review-uuid-456",
"rating": 5,
"review": "Excellent skill!",
"created_at": "2026-04-05T12:00:00Z",
"helpful_count": 12
}
],
"total": 42,
"limit": 20,
"offset": 0
}**Authentication:** None required
---
Flag Review
POST /api/public/v1/marketplace/reviews/{review_id}/flagFlag a review for moderation (requires authentication).
**Path Parameters:**
review_id(string): Review ID
**Query Parameters:**
reason(string): Flag reason (1-500 chars)
**Response:**
{
"success": true,
"review_id": "review-uuid-456",
"status": "flagged"
}**Authentication:** Required (API key or OAuth token)
---
Error Codes
HTTP Status Codes
| Status | Description |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 429 | Rate Limit Exceeded |
| 500 | Internal Server Error |
Error Response Format
All error responses follow this format:
{
"error": "Error type",
"message": "Detailed error message",
"code": "ERROR_CODE",
"details": {
"field": "Additional context"
}
}Common Error Scenarios
Authentication Errors
**401 Unauthorized**
{
"error": "Unauthorized",
"message": "Authentication required. Use X-API-Key or Authorization: Bearer header.",
"code": "AUTH_REQUIRED"
}**401 Invalid API Key**
{
"error": "Unauthorized",
"message": "Invalid or inactive API key",
"code": "INVALID_API_KEY"
}**401 Expired Token**
{
"error": "Unauthorized",
"message": "Invalid or expired OAuth token",
"code": "EXPIRED_TOKEN"
}Permission Errors
**403 Forbidden**
{
"error": "Forbidden",
"message": "Read-only key cannot perform write operations",
"code": "INSUFFICIENT_SCOPE"
}**403 Governance Denied**
{
"error": "Forbidden",
"message": "Agent maturity level insufficient for this action",
"code": "GOVERNANCE_DENIED"
}Validation Errors
**400 Bad Request**
{
"error": "Bad Request",
"message": "Validation failed",
"code": "VALIDATION_ERROR",
"details": {
"field": "skill_type",
"message": "Invalid skill type. Must be one of: api, function, script, docker, container"
}
}**400 Invalid Input**
{
"error": "Bad Request",
"message": "Maximum limit is 100",
"code": "INVALID_LIMIT"
}Not Found Errors
**404 Not Found**
{
"error": "Not Found",
"message": "Skill not found or not approved",
"code": "SKILL_NOT_FOUND"
}**404 Component Not Found**
{
"error": "Not Found",
"message": "Component not found",
"code": "COMPONENT_NOT_FOUND"
}Rate Limiting
**429 Rate Limit Exceeded**
{
"error": "Rate Limit Exceeded",
"message": "Rate limit exceeded. Please try again later.",
"code": "RATE_LIMIT_EXCEEDED",
"retry_after": 60
}Headers:
Retry-After: 60Server Errors
**500 Internal Server Error**
{
"error": "Internal Server Error",
"message": "An unexpected error occurred",
"code": "INTERNAL_ERROR"
}Marketplace-Specific Error Codes
| Code | HTTP Status | Description |
|---|---|---|
| SKILL_NOT_FOUND | 404 | Skill not found or not approved |
| COMPONENT_NOT_FOUND | 404 | Component not found |
| TEMPLATE_NOT_FOUND | 404 | Template not found |
| DOMAIN_NOT_FOUND | 404 | Domain not found |
| AGENT_NOT_FOUND | 404 | Agent template not found |
| ALREADY_PUBLISHED | 409 | Item already published |
| PENDING_APPROVAL | 403 | Item is pending approval |
| APPROVAL_REQUIRED | 403 | Item requires admin approval |
| NOT_OWNER | 403 | User does not own this item |
| INSTALL_FAILED | 422 | Installation failed |
| PACKAGE_INSTALL_FAILED | 422 | Package installation failed |
| INVALID_VERSION | 400 | Invalid version format |
| RATING_EXISTS | 409 | User has already rated this item |
| TENANT_NOT_FOUND | 404 | Tenant context not found |
| TENANT_LIMIT_EXCEEDED | 429 | Tenant quota limit exceeded |
| AGENT_LIMIT_EXCEEDED | 429 | Agent count limit exceeded |
| SKILL_LIMIT_EXCEEDED | 429 | Skill count limit exceeded |
| PACKAGE_NOT_WHITELISTED | 403 | Package not in whitelist |
| PACKAGE_VULNERABILITY | 403 | Package has security vulnerabilities |
| DEPENDENCY_MISSING | 422 | Required dependency missing |
| CONFIG_SCHEMA_INVALID | 400 | Configuration schema invalid |
| INPUT_VALIDATION_FAILED | 400 | Input validation failed |
| MISSING_REQUIRED_FIELD | 400 | Required field missing |
| INVALID_ENUM_VALUE | 400 | Invalid enum value provided |
| DUPLICATE_ENTRY | 409 | Duplicate entry detected |
| CONFLICTING_OPERATION | 409 | Conflicting operation in progress |
| SERVICE_UNAVAILABLE | 503 | Service temporarily unavailable |
| MAINTENANCE_MODE | 503 | System under maintenance |
| MARKETPLACE_DISABLED | 503 | Marketplace feature disabled |
---
Advanced Error Scenarios
Tenant Quota Errors
**429 Too Many Requests - Tenant Agent Limit**
{
"error": "Quota Exceeded",
"message": "Tenant has reached maximum agent limit (10). Upgrade to Team plan for 25 agents.",
"code": "AGENT_LIMIT_EXCEEDED",
"details": {
"current": 10,
"limit": 10,
"plan": "Free",
"upgrade_url": "https://atom-saas.fly.dev/settings/billing"
}
}**Solution:** Upgrade plan or delete unused agents
---
**429 Too Many Requests - Daily Skill Execution Limit**
{
"error": "Quota Exceeded",
"message": "Daily skill execution limit reached (50/50). Resets at midnight UTC.",
"code": "SKILL_LIMIT_EXCEEDED",
"details": {
"current": 50,
"limit": 50,
"resets_at": "2026-04-06T00:00:00Z"
}
}**Solution:** Wait for daily reset or upgrade plan
---
Package Installation Errors
**403 Forbidden - Package Not Whitelisted**
{
"error": "Forbidden",
"message": "Package 'malicious-package' is not whitelisted. Contact administrator to request approval.",
"code": "PACKAGE_NOT_WHITELISTED",
"details": {
"package_name": "malicious-package",
"package_type": "python",
"request_url": "https://atom-saas.fly.dev/admin/packages/request"
}
}**Solution:** Request package whitelisting from admin
---
**403 Forbidden - Package Vulnerability Detected**
{
"error": "Forbidden",
"message": "Package 'old-package' has 2 known security vulnerabilities. Update to version 2.0.0 or later.",
"code": "PACKAGE_VULNERABILITY",
"details": {
"package_name": "old-package",
"current_version": "1.5.0",
"safe_version": "2.0.0",
"vulnerabilities": [
{
"severity": "HIGH",
"cve": "CVE-2024-12345",
"description": "Remote code execution vulnerability"
}
]
}
}**Solution:** Update package to safe version
---
**422 Unprocessable Entity - Dependency Missing**
{
"error": "Installation Failed",
"message": "Required dependency 'pandas' is not installed. Install it first.",
"code": "DEPENDENCY_MISSING",
"details": {
"missing_package": "pandas",
"required_by": "data-analysis-skill",
"install_command": "pip install pandas>=2.0.0"
}
}**Solution:** Install missing dependency
---
Governance Errors
**403 Forbidden - Agent Maturity Insufficient**
{
"error": "Governance Denied",
"message": "Agent maturity 'student' cannot perform action 'send_email'. Required maturity: 'supervised'.",
"code": "GOVERNANCE_DENIED",
"details": {
"agent_id": "agent-uuid-123",
"current_maturity": "student",
"required_maturity": "supervised",
"action": "send_email",
"reason": "Student agents are read-only. Graduate agent to intern for proposal permissions."
}
}**Solution:** Graduate agent to higher maturity level
---
**403 Forbidden - Skill Requires Approval**
{
"error": "Approval Required",
"message": "Skill 'exec-shell-commands' requires explicit approval due to security risk.",
"code": "APPROVAL_REQUIRED",
"details": {
"skill_id": "skill-uuid-456",
"risk_level": "HIGH",
"reason": "Can execute arbitrary shell commands",
"approval_url": "https://atom-saas.fly.dev/admin/skills/approve"
}
}**Solution:** Request admin approval for high-risk skills
---
Validation Errors
**400 Bad Request - Invalid Configuration Schema**
{
"error": "Validation Failed",
"message": "Configuration schema does not match skill requirements.",
"code": "CONFIG_SCHEMA_INVALID",
"details": {
"expected_schema": {
"type": "object",
"properties": {
"api_key": {"type": "string"},
"timeout": {"type": "number"}
},
"required": ["api_key"]
},
"provided_config": {
"api_key": "sk-123",
"invalid_field": "value"
},
"errors": [
"Additional property 'invalid_field' not allowed",
"Missing required property 'timeout'"
]
}
}**Solution:** Fix configuration to match schema
---
**400 Bad Request - Invalid Enum Value**
{
"error": "Validation Failed",
"message": "Invalid value for field 'skill_type'.",
"code": "INVALID_ENUM_VALUE",
"details": {
"field": "skill_type",
"provided_value": "webhook",
"allowed_values": ["api", "function", "script", "docker", "container"]
}
}**Solution:** Use valid enum value
---
**409 Conflict - Duplicate Entry**
{
"error": "Duplicate Entry",
"message": "A skill with this name already exists in your private marketplace.",
"code": "DUPLICATE_ENTRY",
"details": {
"field": "name",
"value": "Data Analysis",
"existing_skill_id": "skill-uuid-789",
"suggestion": "Use a different name or update the existing skill"
}
}**Solution:** Use unique name or update existing entry
---
Service Errors
**503 Service Unavailable - Maintenance Mode**
{
"error": "Service Unavailable",
"message": "Marketplace is under maintenance. Expected downtime: 30 minutes.",
"code": "MAINTENANCE_MODE",
"details": {
"started_at": "2026-04-05T12:00:00Z",
"expected_end": "2026-04-05T12:30:00Z",
"status_page": "https://status.atomagentos.com"
}
}**Solution:** Wait for maintenance to complete
---
**503 Service Unavailable - Marketplace Disabled**
{
"error": "Service Unavailable",
"message": "Marketplace feature is disabled for this tenant.",
"code": "MARKETPLACE_DISABLED",
"details": {
"feature": "public_marketplace",
"reason": "Enterprise plan required",
"upgrade_url": "https://atom-saas.fly.dev/settings/billing"
}
}**Solution:** Upgrade to enable marketplace
---
Troubleshooting Guide
Authentication Issues
Problem: 401 Unauthorized - No API Key Provided
**Symptoms:**
{
"error": "Unauthorized",
"message": "Authentication required. Use X-API-Key or Authorization: Bearer header.",
"code": "AUTH_REQUIRED"
}**Diagnosis:**
- Missing
X-API-Keyheader - Missing
Authorization: Bearerheader - Session cookie expired
**Solutions:**
- **Add API Key Header:**
curl -X GET "https://atom-saas.fly.dev/api/skills/marketplace" \
-H "X-API-Key: sk-your-api-key"- **Add Bearer Token:**
curl -X GET "https://atom-saas.fly.dev/api/skills/marketplace" \
-H "Authorization: Bearer your-access-token"- **Check API Key Format:**
- Must start with
sk- - Only alphanumeric characters after prefix
- Example:
sk-abc123def456
---
Problem: 401 Unauthorized - Invalid API Key
**Symptoms:**
{
"error": "Unauthorized",
"message": "Invalid or inactive API key",
"code": "INVALID_API_KEY"
}**Diagnosis:**
- API key doesn't exist in database
- API key is inactive (
is_active=False) - API key has been revoked
**Solutions:**
- **Verify Key in Dashboard:**
- Go to Settings → API Keys
- Check key status is "Active"
- Copy key again (ensure no extra spaces)
- **Generate New Key:**
- Delete old key
- Create new key
- Update application with new key
- **Check Key Scope:**
# Verify key has correct scope
key = db.query(APIKey).filter(key_value="sk-your-key").first()
print(f"Scope: {key.scope}") # Should be "read_write" for operations---
Problem: 401 Unauthorized - Expired OAuth Token
**Symptoms:**
{
"error": "Unauthorized",
"message": "Invalid or expired OAuth token",
"code": "EXPIRED_TOKEN"
}**Diagnosis:**
- Access token expired (typically 1 hour lifetime)
- Refresh token also expired
- Token revoked by user
**Solutions:**
- **Refresh Access Token:**
# Use refresh token to get new access token
response = requests.post("https://atom-saas.fly.dev/oauth/token", data={
"grant_type": "refresh_token",
"refresh_token": refresh_token
})
new_access_token = response.json()["access_token"]- **Re-authenticate User:**
# Redirect user to OAuth flow
auth_url = f"https://atom-saas.fly.dev/oauth/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}"
# Redirect user to auth_url---
Permission Issues
Problem: 403 Forbidden - Insufficient Scope
**Symptoms:**
{
"error": "Forbidden",
"message": "Read-only key cannot perform write operations",
"code": "INSUFFICIENT_SCOPE"
}**Diagnosis:**
- API key has
readscope - Attempting write operation (POST, PUT, DELETE)
**Solutions:**
- **Check Key Scope:**
key = db.query(APIKey).filter(key_value="sk-your-key").first()
if key.scope == "read":
print("Key is read-only. Need read_write scope.")- **Create Read-Write Key:**
- Delete read-only key
- Create new key with scope="read_write"
- **Use Correct Key:**
# Use read_write key for write operations
curl -X POST "https://atom-saas.fly.dev/api/skills/publish" \
-H "X-API-Key: sk-read-write-key" \
-H "Content-Type: application/json" \
-d '{"skill_id": "..."}'---
Problem: 403 Forbidden - Governance Denied
**Symptoms:**
{
"error": "Forbidden",
"message": "Agent maturity level insufficient for this action",
"code": "GOVERNANCE_DENIED"
}**Diagnosis:**
- Agent maturity too low for action
- Action requires higher maturity level
**Maturity Levels:**
student: Read-only (browse, search)intern: Proposals (requires approval)supervised: Live monitoring (can act with supervision)autonomous: Full access (can supervise others)
**Solutions:**
- **Graduate Agent:**
# Check graduation readiness
from core.agent_graduation_service import AgentGraduationService
grad_service = AgentGraduationService(db)
result = grad_service.check_unified_graduation(
agent_id="agent-uuid-123",
tenant_id=tenant_id,
target_maturity="SUPERVISED"
)
if result["ready"]:
# Graduate agent
grad_service graduate_agent(agent_id, "SUPERVISED")- **Use Higher Maturity Agent:**
# Find supervised agent
agent = db.query(Agent).filter(
Agent.maturity == "supervised",
Agent.tenant_id == tenant_id
).first()
# Use this agent for the action---
Rate Limiting Issues
Problem: 429 Too Many Requests
**Symptoms:**
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
"error": "Rate Limit Exceeded",
"message": "Rate limit exceeded. Please try again later.",
"code": "RATE_LIMIT_EXCEEDED"
}**Diagnosis:**
- Exceeded request limit (60-100 req/min depending on auth)
- Too many requests from same IP/API key
**Solutions:**
- **Implement Exponential Backoff:**
import time
import random
def make_request_with_backoff(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code != 429:
return response
# Exponential backoff: 2^attempt + random jitter
wait_time = (2 ** attempt) + random.uniform(0, 1)
retry_after = int(response.headers.get("Retry-After", wait_time))
print(f"Rate limited. Waiting {retry_after} seconds...")
time.sleep(retry_after)
return response # Last attempt- **Cache Responses:**
from functools import lru_cache
import time
@lru_cache(maxsize=100)
def get_marketplace_skills(cache_buster=None):
"""Cache marketplace skills for 5 minutes"""
response = requests.get(
"https://atom-saas.fly.dev/api/skills/marketplace",
headers={"X-API-Key": "sk-your-key"}
)
return response.json()
# Use cache buster to invalidate
cache_key = int(time.time() // 300) # New key every 5 minutes
skills = get_marketplace_skills(cache_buster=cache_key)- **Batch Operations:**
# Instead of multiple requests
for skill_id in skill_ids:
response = requests.get(f"/api/skills/{skill_id}") # Bad: N requests
# Use single request with IDs
response = requests.get("/api/skills", params={"ids": ",".join(skill_ids)}) # Good: 1 request- **Monitor Rate Limit Headers:**
response = requests.get(url, headers=headers)
# Check rate limit status
remaining = int(response.headers.get("X-RateLimit-Remaining", 0))
limit = int(response.headers.get("X-RateLimit-Limit", 60))
if remaining < 10:
print(f"Warning: Only {remaining} requests remaining (limit: {limit})")
# Slow down requests---
Installation Failures
Problem: 422 Unprocessable Entity - Package Not Whitelisted
**Symptoms:**
{
"error": "Installation Failed",
"message": "Package 'malicious-package' is not whitelisted.",
"code": "PACKAGE_NOT_WHITELISTED"
}**Diagnosis:**
- Skill requires package not in whitelist
- Security policy blocks unknown packages
**Solutions:**
- **Request Package Whitelist:**
# Submit package for approval
curl -X POST "https://atom-saas.fly.dev/api/packages/request" \
-H "X-API-Key: sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"package_name": "data-package",
"package_type": "python",
"version": "1.0.0",
"reason": "Required for data analysis skill"
}'- **Use Alternative Package:**
# Find whitelisted alternative
from core.package_whitelist_service import PackageWhitelistService
service = PackageWhitelistService(db)
alternatives = service.search_packages(
query="data processing",
package_type="python"
)
print(f"Alternatives: {alternatives}")- **Contact Admin:**
- Email: support@atomagentos.com
- Include: package name, version, use case
---
Problem: 403 Forbidden - Package Vulnerability
**Symptoms:**
{
"error": "Forbidden",
"message": "Package 'old-package' has 2 known security vulnerabilities.",
"code": "PACKAGE_VULNERABILITY"
}**Diagnosis:**
- Package has known CVEs
- Automated security scan detected issues
**Solutions:**
- **Update Package:**
# Check for safe version
from core.package_installation_service import PackageInstallationService
service = PackageInstallationService(db)
safe_version = service.get_safe_version("old-package")
print(f"Update to version: {safe_version}") # e.g., "2.0.0"- **Modify Skill Requirements:**
{
"python_packages": [
{
"name": "old-package",
"version": "2.0.0", // Updated to safe version
"type": "python"
}
]
}- **Review CVE Details:**
# Check vulnerability details
curl "https://atom-saas.fly.dev/api/packages/old-package/vulnerabilities" \
-H "X-API-Key: sk-your-key"---
Problem: 422 Unprocessable Entity - Dependency Missing
**Symptoms:**
{
"error": "Installation Failed",
"message": "Required dependency 'pandas' is not installed.",
"code": "DEPENDENCY_MISSING"
}**Diagnosis:**
- Skill requires package that isn't installed
- Dependency chain incomplete
**Solutions:**
- **Install Missing Dependency:**
from core.package_installation_service import PackageInstallationService
service = PackageInstallationService(db)
# Install dependency
result = await service.install_package(
tenant_id=tenant_id,
package_name="pandas",
package_type="python",
version=">=2.0.0"
)
print(f"Installation: {result['status']}")- **Install Skill with Dependencies:**
# Skill installation should auto-install dependencies
curl -X POST "https://atom-saas.fly.dev/api/skills/install" \
-H "X-API-Key: sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"skill_id": "skill-uuid-123",
"install_dependencies": true
}'- **Verify Dependencies:**
# Check installed packages
service = PackageInstallationService(db)
installed = service.list_installed_packages(tenant_id)
print("Installed packages:")
for pkg in installed:
print(f" - {pkg['name']}: {pkg['version']}")---
Validation Errors
Problem: 400 Bad Request - Invalid Configuration
**Symptoms:**
{
"error": "Validation Failed",
"message": "Configuration schema does not match skill requirements.",
"code": "CONFIG_SCHEMA_INVALID"
}**Diagnosis:**
- Config doesn't match skill schema
- Missing required fields
- Invalid data types
**Solutions:**
- **Get Skill Schema:**
# Retrieve skill schema first
curl -X GET "https://atom-saas.fly.dev/api/skills/skill-uuid-123" \
-H "X-API-Key: sk-your-key"
# Response includes config_schema
{
"config_schema": {
"type": "object",
"properties": {
"api_key": {"type": "string"},
"timeout": {"type": "number", "default": 30}
},
"required": ["api_key"]
}
}- **Match Configuration to Schema:**
# Build config matching schema
config = {
"api_key": "sk-123", # Required
"timeout": 60 # Optional, with default
}
# Validate config before sending
from jsonschema import validate
validate(instance=config, schema=skill["config_schema"])- **Use Schema Builder:**
# Auto-generate config form from schema
def build_config_form(schema):
form = {}
for field_name, field_def in schema["properties"].items():
required = field_name in schema.get("required", [])
form[field_name] = {
"type": field_def["type"],
"required": required,
"default": field_def.get("default")
}
return form
form = build_config_form(skill["config_schema"])---
Common Mistakes
Mistake 1: Missing Content-Type Header
**Wrong:**
curl -X POST "https://atom-saas.fly.dev/api/skills/publish" \
-H "X-API-Key: sk-your-key" \
-d '{"skill_id": "..."}'**Correct:**
curl -X POST "https://atom-saas.fly.dev/api/skills/publish" \
-H "X-API-Key: sk-your-key" \
-H "Content-Type: application/json" \
-d '{"skill_id": "..."}'---
Mistake 2: Wrong API Key for Environment
**Problem:** Using production key in development
**Solution:**
import os
# Use environment-specific keys
if os.environ.get("ENV") == "production":
API_KEY = os.environ["PRODUCTION_API_KEY"]
BASE_URL = "https://atom-saas.fly.dev"
else:
API_KEY = os.environ["DEV_API_KEY"]
BASE_URL = "https://atom-saas-dev.fly.dev"---
Mistake 3: Ignoring Rate Limit Headers
**Wrong:**
# Doesn't check rate limits
while True:
response = requests.get(url, headers=headers)**Correct:**
# Checks rate limits
while True:
response = requests.get(url, headers=headers)
remaining = int(response.headers.get("X-RateLimit-Remaining", 0))
if remaining == 0:
reset_time = int(response.headers.get("X-RateLimit-Reset", 0))
wait_seconds = reset_time - int(time.time())
time.sleep(wait_seconds)---
Mistake 4: Not Handling Pagination
**Wrong:**
# Only gets first page
response = requests.get(f"{url}?limit=50")
skills = response.json()["skills"]**Correct:**
# Gets all pages
all_skills = []
offset = 0
limit = 50
while True:
response = requests.get(f"{url}?limit={limit}&offset={offset}")
data = response.json()
all_skills.extend(data["skills"])
if not data["has_more"]:
break
offset += limit---
Mistake 5: Hardcoding IDs
**Wrong:**
# Hardcoded ID breaks when skill changes
skill_id = "skill-uuid-123"**Correct:**
# Search for skill by name
response = requests.get(f"{url}?query=data%20analysis")
skills = response.json()["skills"]
if skills:
skill_id = skills[0]["id"] # Use actual ID---
Debugging Tools
API Test Console
Built-in API explorer for testing endpoints:
# Open API test console
open "https://atom-saas.fly.dev/api/test-console"Features:
- Interactive API testing
- Request/response inspection
- Authentication handling
- Error explanation
---
Logging
Enable debug logging:
import logging
# Enable request logging
logging.basicConfig(level=logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
# Make request
response = requests.get(url, headers=headers)
# Logs show:
# DEBUG:urllib3.connectionpool:Starting new HTTPS connection
# DEBUG:urllib3.connectionpool:https://atom-saas.fly.dev:443 "GET /api/skills/marketplace HTTP/1.1" 200 1234---
Response Inspection
Inspect full response details:
def inspect_response(response):
"""Print detailed response information."""
print(f"Status: {response.status_code}")
print(f"Headers: {dict(response.headers)}")
print(f"Body: {response.text}")
# Check rate limits
if "X-RateLimit-Remaining" in response.headers:
remaining = response.headers["X-RateLimit-Remaining"]
limit = response.headers["X-RateLimit-Limit"]
print(f"Rate Limit: {remaining}/{limit} remaining")
# Check for errors
try:
data = response.json()
if "error" in data:
print(f"Error Code: {data.get('code')}")
print(f"Error Message: {data.get('message')}")
if "details" in data:
print(f"Details: {data['details']}")
except:
pass
# Use it
response = requests.get(url, headers=headers)
inspect_response(response)---
Monitoring and Alerting
Health Checks
Monitor API health:
# Check API status
curl -X GET "https://atom-saas.fly.dev/api/health"**Response:**
{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2026-04-05T12:00:00Z",
"services": {
"database": "healthy",
"redis": "healthy",
"marketplace": "healthy"
}
}---
Error Tracking
Track errors over time:
from collections import defaultdict
class ErrorTracker:
def __init__(self):
self.errors = defaultdict(int)
def log_error(self, response):
if response.status_code >= 400:
try:
data = response.json()
error_code = data.get("code", "UNKNOWN")
self.errors[error_code] += 1
except:
self.errors["UNKNOWN"] += 1
def get_summary(self):
return dict(self.errors)
# Use it
tracker = ErrorTracker()
for i in range(100):
response = requests.get(url, headers=headers)
tracker.log_error(response)
print("Error Summary:")
print(tracker.get_summary())
# Output: {"RATE_LIMIT_EXCEEDED": 5, "SKILL_NOT_FOUND": 2}Troubleshooting Guide
Authentication Issues
- **Check API key format**: Should be
sk-followed by alphanumeric characters - **Verify key is active**: Check in admin dashboard
- **Check key scope**: Read-only keys cannot write
- **OAuth token expired**: Obtain new token
Permission Issues
- **Verify user permissions**: Check RBAC settings
- **Check agent maturity**: Higher maturity required for some actions
- **Tenant context required**: Some endpoints need tenant context
Rate Limiting
- **Default limits**: 60-100 requests per minute depending on auth
- **Backoff strategy**: Implement exponential backoff
- **Retry-After header**: Use provided retry delay
Installation Failures
- **Check dependencies**: Verify packages are whitelisted
- **Agent maturity**: Some skills require minimum maturity
- **Config validation**: Verify config schema matches
---
Rate Limiting
Default Limits
- **Unauthenticated**: 20 requests/minute
- **API Key (read)**: 60 requests/minute
- **API Key (read_write)**: 60 requests/minute
- **OAuth Token**: 100 requests/minute
- **Federation**: 100 requests/minute per IP
Rate Limit Headers
All responses include rate limit headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1775411393Best Practices
- **Check rate limit headers**: Monitor remaining quota
- **Implement backoff**: Exponential backoff on 429
- **Use caching**: Cache marketplace data locally
- **Batch requests**: Combine multiple operations when possible
---
SDK Examples
Python SDK
from atom_saas import MarketplaceClient
# Initialize client
client = MarketplaceClient(api_key="sk-your-key")
# Browse skills
skills = client.skills.browse(category="productivity", limit=10)
# Install skill
result = client.skills.install(
skill_id="skill-uuid-123",
agent_id="agent-uuid-456"
)
# Rate skill
client.skills.rate(
skill_id="skill-uuid-123",
rating=5,
review="Excellent!"
)JavaScript SDK
import { MarketplaceClient } from '@atom-saas/sdk';
// Initialize client
const client = new MarketplaceClient({ apiKey: 'sk-your-key' });
// Browse skills
const skills = await client.skills.browse({
category: 'productivity',
limit: 10
});
// Install skill
const result = await client.skills.install({
skillId: 'skill-uuid-123',
agentId: 'agent-uuid-456'
});
// Rate skill
await client.skills.rate({
skillId: 'skill-uuid-123',
rating: 5,
review: 'Excellent!'
});cURL Examples
# Browse skills
curl -X GET "https://atom-saas.fly.dev/api/skills/marketplace?category=productivity&limit=10" \
-H "X-API-Key: sk-your-key"
# Install skill
curl -X POST "https://atom-saas.fly.dev/api/skills/install" \
-H "X-API-Key: sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"skill_id": "skill-uuid-123",
"agent_id": "agent-uuid-456"
}'
# Rate skill
curl -X POST "https://atom-saas.fly.dev/api/skills/rate/skill-uuid-123" \
-H "X-API-Key: sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"rating": 5,
"review": "Excellent!"
}'---
Changelog
v1.0.0 (2026-04-05)
- Initial marketplace API documentation
- Skill, Agent, Domain, Canvas, Workflow marketplaces
- Public marketplace API
- Private marketplace endpoints
- Federation protocol
- Comprehensive error codes and troubleshooting
---
Support
For issues, questions, or feature requests:
- **Documentation**: https://docs.atomagentos.com
- **GitHub Issues**: https://github.com/rush86999/atom-saas/issues
- **Email**: support@atomagentos.com