ATOM Documentation

← Back to App

Marketplace API Documentation

Complete API reference for all marketplace endpoints in the ATOM SaaS platform.

Table of Contents


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-here

OAuth Bearer Token

Authorization: Bearer your-access-token

Session Authentication

For web-based requests, session cookies are automatically handled.


Skill Marketplace

Base URL: /api/skills

Browse Marketplace

GET /api/skills/marketplace

Browse and search for skills in the marketplace.

Query Parameters:

ParameterTypeRequiredDefaultDescription
querystringNo-Search term
categorystringNo-Filter by category
tagsstringNo-Comma-separated tags
skill_typestringNo-Filter by type (api, function, script, docker, container)
sort_bystringNopopularitySort field
limitintegerNo50Max results
offsetintegerNo0Pagination 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/publish

Publish 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/install

Install 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/version

Create a frozen version of a skill.

Query Parameters:

  • skill_id (string): Skill ID
  • version_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/browse

Browse available agent templates.

Query Parameters:

ParameterTypeRequiredDefaultDescription
limitintegerNo50Max results
offsetintegerNo0Pagination 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:

ParameterTypeRequiredDescription
namestringYesAgent name
descriptionstringYesAgent description
pricefloatNoPrice (default: 0.0)
categorystringNoCategory

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/submit

Submit 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-submissions

List 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}/approve

Approve 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}/reject

Reject 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/search

Search marketplace for domains.

Query Parameters:

ParameterTypeRequiredDefaultDescription
qstringNo-Search query
categorystringNo-Filter by category
tagsstringNo-Comma-separated tags
max_pricefloatNo-Maximum price
limitintegerNo20Max 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/trending

Get 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/stats

Get 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/install

Install 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}/rate

Rate 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/components

Browse marketplace components.

Query Parameters:

ParameterTypeRequiredDefaultDescription
querystringNo-Search query
categorystringNo-Filter by category
tagsstringNo-Comma-separated tags
component_typestringNo-Filter by type
min_pricefloatNo-Minimum price
max_pricefloatNo-Maximum price
is_freebooleanNofalseFree only
is_featuredbooleanNofalseFeatured only
sort_bystringNocreated_atSort field
sort_orderstringNodescSort order (asc/desc)
limitintegerNo50Max results (max 100)
offsetintegerNo0Pagination 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/publish

Submit 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}/approve

Approve 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}/reject

Reject 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/install

Install 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}/rate

Rate 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}/ratings

Get ratings and reviews for a component.

Path Parameters:

  • component_id (string): Component ID

Query Parameters:

ParameterTypeRequiredDefaultDescription
limitintegerNo20Max ratings (max 100)
offsetintegerNo0Pagination 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/categories

List all component categories with counts.

Response:

{ "categories": [ { "name": "ui", "count": 45 }, { "name": "charts", "count": 23 } ] }

Authentication: None required


List Tags

GET /api/canvas-marketplace/tags

List 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/templates

Get workflow templates with filtering.

Query Parameters:

ParameterTypeRequiredDefaultDescription
categorystringNo-Filter by category
template_typestringNo-Filter by type (legacy, advanced, industry)
industrystringNo-Filter by industry
tagslistNo-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/types

Get 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/featured

Get 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}/import

Import 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/advanced

Create 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-workflow

Create a workflow from an advanced template.

Path Parameters:

  • template_id (string): Template ID

Query Parameters:

  • workflow_name (string): Workflow name
  • parameters (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/import

Import 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/export

Export 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/statistics

Get 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/private

List tenant's private skills (created + installed).

Query Parameters:

ParameterTypeRequiredDefaultDescription
querystringNo-Search term
categorystringNo-Filter by category
skill_typestringNo-Filter by type
is_installedbooleanNo-Filter by installation status
sort_bystringNonameSort field
sort_orderstringNoascSort order (asc/desc)
limitintegerNo50Max results
offsetintegerNo0Pagination 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/install

Install 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/private

Create 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/skills

Browse the public skill marketplace (read-only API).

Query Parameters:

ParameterTypeRequiredDefaultDescription
querystringNo-Search term
categorystringNo-Filter by category
tagsstringNo-Comma-separated tags
skill_typestringNo-Filter by type
is_freebooleanNofalseFree only
is_featuredbooleanNofalseFeatured only
sort_bystringNocreated_atSort field
sort_orderstringNodescSort order (asc/desc)
limitintegerNo50Max results (max 100)
offsetintegerNo0Pagination 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/categories

Get all skill categories.

Response:

{ "categories": ["productivity", "sales", "finance", "communication"] }

Authentication: Optional


Get Tags

GET /api/public/v1/marketplace/tags

Get 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/submit

Submit 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}/rate

Rate 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}/reviews

Get reviews for a skill (no authentication required).

Path Parameters:

  • skill_id (string): Skill ID

Query Parameters:

ParameterTypeRequiredDefaultDescription
limitintegerNo20Max reviews (1-100)
offsetintegerNo0Pagination 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}/flag

Flag 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

StatusDescription
200Success
201Created
400Bad Request
401Unauthorized
403Forbidden
404Not Found
429Rate Limit Exceeded
500Internal 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: 60

Server Errors

500 Internal Server Error

{ "error": "Internal Server Error", "message": "An unexpected error occurred", "code": "INTERNAL_ERROR" }

Marketplace-Specific Error Codes

CodeHTTP StatusDescription
SKILL_NOT_FOUND404Skill not found or not approved
COMPONENT_NOT_FOUND404Component not found
TEMPLATE_NOT_FOUND404Template not found
DOMAIN_NOT_FOUND404Domain not found
AGENT_NOT_FOUND404Agent template not found
ALREADY_PUBLISHED409Item already published
PENDING_APPROVAL403Item is pending approval
APPROVAL_REQUIRED403Item requires admin approval
NOT_OWNER403User does not own this item
INSTALL_FAILED422Installation failed
PACKAGE_INSTALL_FAILED422Package installation failed
INVALID_VERSION400Invalid version format
RATING_EXISTS409User has already rated this item
TENANT_NOT_FOUND404Tenant context not found
TENANT_LIMIT_EXCEEDED429Tenant quota limit exceeded
AGENT_LIMIT_EXCEEDED429Agent count limit exceeded
SKILL_LIMIT_EXCEEDED429Skill count limit exceeded
PACKAGE_NOT_WHITELISTED403Package not in whitelist
PACKAGE_VULNERABILITY403Package has security vulnerabilities
DEPENDENCY_MISSING422Required dependency missing
CONFIG_SCHEMA_INVALID400Configuration schema invalid
INPUT_VALIDATION_FAILED400Input validation failed
MISSING_REQUIRED_FIELD400Required field missing
INVALID_ENUM_VALUE400Invalid enum value provided
DUPLICATE_ENTRY409Duplicate entry detected
CONFLICTING_OPERATION409Conflicting operation in progress
SERVICE_UNAVAILABLE503Service temporarily unavailable
MAINTENANCE_MODE503System under maintenance
MARKETPLACE_DISABLED503Marketplace 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-Key header
  • Missing Authorization: Bearer header
  • Session cookie expired

Solutions:

  1. Add API Key Header:
curl -X GET "https://atom-saas.fly.dev/api/skills/marketplace" \ -H "X-API-Key: sk-your-api-key"
  1. Add Bearer Token:
curl -X GET "https://atom-saas.fly.dev/api/skills/marketplace" \ -H "Authorization: Bearer your-access-token"
  1. 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:

  1. Verify Key in Dashboard:

    • Go to Settings → API Keys
    • Check key status is "Active"
    • Copy key again (ensure no extra spaces)
  2. Generate New Key:

    • Delete old key
    • Create new key
    • Update application with new key
  3. 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:

  1. 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"]
  1. 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 read scope
  • Attempting write operation (POST, PUT, DELETE)

Solutions:

  1. 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.")
  1. Create Read-Write Key:

    • Delete read-only key
    • Create new key with scope="read_write"
  2. 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:

  1. 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")
  1. 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:

  1. 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
  1. 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)
  1. 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
  1. 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:

  1. 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" }'
  1. 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}")
  1. Contact Admin:

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:

  1. 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"
  1. Modify Skill Requirements:
{ "python_packages": [ { "name": "old-package", "version": "2.0.0", // Updated to safe version "type": "python" } ] }
  1. 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:

  1. 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']}")
  1. 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 }'
  1. 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:

  1. 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"] } }
  1. 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"])
  1. 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

  1. Check API key format: Should be sk- followed by alphanumeric characters
  2. Verify key is active: Check in admin dashboard
  3. Check key scope: Read-only keys cannot write
  4. OAuth token expired: Obtain new token

Permission Issues

  1. Verify user permissions: Check RBAC settings
  2. Check agent maturity: Higher maturity required for some actions
  3. Tenant context required: Some endpoints need tenant context

Rate Limiting

  1. Default limits: 60-100 requests per minute depending on auth
  2. Backoff strategy: Implement exponential backoff
  3. Retry-After header: Use provided retry delay

Installation Failures

  1. Check dependencies: Verify packages are whitelisted
  2. Agent maturity: Some skills require minimum maturity
  3. 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: 1775411393

Best Practices

  1. Check rate limit headers: Monitor remaining quota
  2. Implement backoff: Exponential backoff on 429
  3. Use caching: Cache marketplace data locally
  4. 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: