ATOM Documentation

← Back to App

ATOM SaaS - Developer Integration Guide

Version: v13.0 Last Updated: 2026-04-05

This guide provides comprehensive documentation for integrating with the ATOM SaaS marketplace ecosystem, including API integration patterns, authentication, publishing, installing, webhooks, and best practices.

Table of Contents

  1. Overview
  2. Authentication & Authorization
  3. Marketplace API Integration
  4. Publishing to Marketplace
  5. Installing from Marketplace
  6. Webhook Integration
  7. Rate Limiting & Best Practices
  8. Error Handling
  9. SDK Reference
  10. Testing Your Integration

Overview

The ATOM SaaS marketplace ecosystem enables developers to:

  • Publish AI agents, skills, canvases, and domains to a public marketplace
  • Discover and install components from other instances via federation protocol
  • Monetize contributions through community ratings and usage tracking
  • Integrate marketplace functionality into custom applications

Marketplace Types

ATOM SaaS supports four marketplace types:

Marketplace TypeDescriptionBase Path
Agent MarketplacePre-built AI agents with defined capabilities/api/agent-marketplace
Skill MarketplaceReusable skill components for agents/api/skill-marketplace
Canvas MarketplaceAgent workspace templates/api/canvas-marketplace
Domain MarketplaceSpecialized knowledge domains/api/domain-marketplace

Federation Protocol

ATOM instances can share components via federation protocol:

  • Federation Base URL: https://atom-saas.fly.dev/api/federation
  • Authentication: X-Federation-Key header with shared secret
  • Discovery: /api/federation/v1/marketplace/agents
  • Download: /api/federation/v1/marketplace/agents/{agent_id}/bundle

Authentication & Authorization

API Authentication

ATOM SaaS uses multiple authentication mechanisms depending on the endpoint:

1. Tenant Context (Required for Most Operations)

All marketplace operations require tenant context:

# Python headers = { "X-Tenant-ID": "your-tenant-id", "Authorization": f"Bearer {api_token}" }
// TypeScript const headers = { "X-Tenant-ID": "your-tenant-id", "Authorization": `Bearer ${apiToken}` };

2. Federation Authentication

For federation protocol, use federation key:

# Python headers = { "X-Federation-Key": "your-federation-key", "X-Tederation-Source": "https://your-instance.fly.dev" }
// TypeScript const headers = { "X-Federation-Key": "your-federation-key", "X-Federation-Source": "https://your-instance.fly.dev" };

3. Admin Key Bypass

For testing and administrative operations:

# Python headers = { "X-Admin-Key": "your-admin-key" }

⚠️ SECURITY WARNING: Never use admin keys in production applications.

Obtaining Credentials

  1. API Token: Generate via tenant settings UI
  2. Federation Key: Generate via federation settings (requires admin)
  3. Tenant ID: Available in tenant settings dashboard

Marketplace API Integration

Base URL

Production: https://atom-saas.fly.dev/api

Client Libraries

Python Client

from atom_marketplace import MarketplaceClient client = MarketplaceClient( base_url="https://atom-saas.fly.dev/api", tenant_id="your-tenant-id", api_token="your-api-token" ) # List agents agents = client.list_agents( marketplace_type="public", capability="sales", min_rating=4.0 ) # Install agent client.install_agent( agent_id="agent-123", target_tenant_id="your-tenant-id" )

TypeScript Client

import { MarketplaceClient } from '@atom-saas/marketplace-sdk'; const client = new MarketplaceClient({ baseUrl: 'https://atom-saas.fly.dev/api', tenantId: 'your-tenant-id', apiToken: 'your-api-token' }); // List agents const agents = await client.listAgents({ marketplaceType: 'public', capability: 'sales', minRating: 4.0 }); // Install agent await client.installAgent('agent-123', 'your-tenant-id');

Core Operations

Listing Components

# List public agents curl -X GET "https://atom-saas.fly.dev/api/agent-marketplace/agents" \ -H "X-Tenant-ID: your-tenant-id" \ -H "Authorization: Bearer your-api-token" \ -G \ --data-urlencode "marketplace_type=public" \ --data-urlencode "capability=sales" \ --data-urlencode "min_rating=4.0" # List skills curl -X GET "https://atom-saas.fly.dev/api/skill-marketplace/skills" \ -H "X-Tenant-ID: your-tenant-id" \ -H "Authorization: Bearer your-api-token" # List canvases curl -X GET "https://atom-saas.fly.dev/api/canvas-marketplace/components" \ -H "X-Tenant-ID: your-tenant-id" \ -H "Authorization: Bearer your-api-token"

Searching Components

# Search agents curl -X GET "https://atom-saas.fly.dev/api/agent-marketplace/agents/search" \ -H "X-Tenant-ID: your-tenant-id" \ -H "Authorization: Bearer your-api-token" \ -G \ --data-urlencode "query=sales automation" \ --data-urlencode "capability=crm"

Getting Component Details

# Get agent details curl -X GET "https://atom-saas.fly.dev/api/agent-marketplace/agents/{agent_id}" \ -H "X-Tenant-ID: your-tenant-id" \ -H "Authorization: Bearer your-api-token" # Get skill details curl -X GET "https://atom-saas.fly.dev/api/skill-marketplace/skills/{skill_id}" \ -H "X-Tenant-ID: your-tenant-id" \ -H "Authorization: Bearer your-api-token"

Publishing to Marketplace

Publishing Agents

# Python from atom_marketplace import MarketplaceClient client = MarketplaceClient(...) # Publish to public marketplace result = client.publish_agent( agent_id="atom_main", marketplace_type="public", name="Sales Automation Agent", description="Automated sales outreach and CRM management", capabilities=["sales", "crm", "outreach"], maturity_level="supervised", pricing_tier="team", tags=["sales", "automation", "crm"], documentation_url="https://docs.example.com/sales-agent" )
// TypeScript const result = await client.publishAgent({ agentId: 'atom_main', marketplaceType: 'public', name: 'Sales Automation Agent', description: 'Automated sales outreach and CRM management', capabilities: ['sales', 'crm', 'outreach'], maturityLevel: 'supervised', pricingTier: 'team', tags: ['sales', 'automation', 'crm'], documentationUrl: 'https://docs.example.com/sales-agent' });

Publishing Skills

# Python result = client.publish_skill( skill_id="salesforce_integration", marketplace_type="public", name="Salesforce Integration", description="Bi-directional Salesforce sync", category="integration", capabilities=["crm", "salesforce"], tags=["crm", "sales", "integration"], version="1.0.0" )

Publishing Canvases

# Python result = client.publish_canvas( canvas_id="sales_outreach_template", marketplace_type="public", name="Sales Outreach Template", description="Complete sales outreach workflow canvas", category="sales", agent_roles=["sales_representative", "manager"], tags=["sales", "outreach", "template"] )

Publishing Domains

# Python result = client.publish_domain( domain_id="sales_knowledge", marketplace_type="public", name="Sales Knowledge Base", description="Comprehensive sales methodology and best practices", category="sales", topics=["methodology", "best_practices", "metrics"], tags=["sales", "knowledge", "training"] )

Approval Workflow

Public marketplace submissions require approval:

  1. Submit component with marketplace_type="public"
  2. Review by ATOM team (automated checks + manual review)
  3. Approval if component meets quality standards
  4. Publication to public marketplace

Private marketplace: Components published with marketplace_type="private" are immediately available without approval.


Installing from Marketplace

Installing Agents

# Python from atom_marketplace import MarketplaceClient client = MarketplaceClient(...) # Install agent result = client.install_agent( agent_id="sales_automation_agent", source_tenant_id="publisher-tenant-id", target_tenant_id="your-tenant-id", install_config={ "api_keys": { "salesforce": "your-salesforce-key" }, "settings": { "auto_approve": False, "max_daily_tasks": 100 } } )
// TypeScript const result = await client.installAgent({ agentId: 'sales_automation_agent', sourceTenantId: 'publisher-tenant-id', targetTenantId: 'your-tenant-id', installConfig: { apiKeys: { salesforce: 'your-salesforce-key' }, settings: { autoApprove: false, maxDailyTasks: 100 } } });

Installing Skills

# Python result = client.install_skill( skill_id="salesforce_integration", source_tenant_id="publisher-tenant-id", target_tenant_id="your-tenant-id" )

Installing Canvases

# Python result = client.install_canvas( canvas_id="sales_outreach_template", source_tenant_id="publisher-tenant-id", target_tenant_id="your-tenant-id" )

Installation Validation

ATOM automatically validates:

  • Agent limits: Does target tenant have capacity?
  • Plan restrictions: Is component available for tenant's plan?
  • Dependencies: Are required skills/capabilities present?
  • Configuration: Are required settings provided?

Webhook Integration

Setting Up Webhooks

ATOM can notify your application about marketplace events:

# Python from atom_marketplace import MarketplaceClient client = MarketplaceClient(...) # Create webhook webhook = client.create_webhook( url="https://your-app.com/webhooks/marketplace", events=["component.installed", "component.updated", "component.rated"], secret="your-webhook-secret" )
// TypeScript const webhook = await client.createWebhook({ url: 'https://your-app.com/webhooks/marketplace', events: ['component.installed', 'component.updated', 'component.rated'], secret: 'your-webhook-secret' });

Webhook Events

EventDescriptionPayload
component.publishedComponent published to marketplace{component_type, component_id, marketplace_type}
component.installedComponent installed by tenant{component_type, component_id, tenant_id}
component.updatedComponent updated{component_type, component_id, version}
component.ratedComponent rated by user{component_type, component_id, rating}
component.approvedComponent approved for public marketplace{component_type, component_id}

Verifying Webhook Signatures

# Python import hmac import hashlib def verify_webhook(payload, signature, secret): expected_signature = hmac.new( secret.encode(), payload.encode(), hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected_signature, signature)
// TypeScript import crypto from 'crypto'; function verifyWebhook(payload: string, signature: string, secret: string): boolean { const expectedSignature = crypto .createHmac('sha256', secret) .update(payload) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(expectedSignature), Buffer.from(signature) ); }

Rate Limiting & Best Practices

Rate Limits

ATOM enforces rate limits to ensure fair usage:

AuthenticationLimitWindow
Unauthenticated100 requests/hourPer IP
API Token10,000 requests/hourPer tenant
Federation Key1,000 requests/hourPer federation key
Admin KeyNo limitPer admin key

Rate Limit Headers

All API responses include rate limit headers:

X-RateLimit-Limit: 10000 X-RateLimit-Remaining: 9999 X-RateLimit-Reset: 1775414400

Handling Rate Limits

# Python import time from atom_marketplace import MarketplaceClient client = MarketplaceClient(...) max_retries = 3 for attempt in range(max_retries): try: result = client.list_agents() break except RateLimitError as e: if attempt < max_retries - 1: retry_after = e.retry_after or 60 print(f"Rate limited. Retrying after {retry_after}s") time.sleep(retry_after) else: raise
// TypeScript async function withRetry<T>( fn: () => Promise<T>, maxRetries: number = 3 ): Promise<T> { for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await fn(); } catch (error) { if (error instanceof RateLimitError && attempt < maxRetries - 1) { const retryAfter = error.retryAfter || 60; console.log(`Rate limited. Retrying after ${retryAfter}s`); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); } else { throw error; } } } throw new Error('Max retries exceeded'); }

Best Practices

1. Use Pagination for Large Lists

# Python all_agents = [] page = 1 page_size = 100 while True: response = client.list_agents( marketplace_type="public", page=page, page_size=page_size ) all_agents.extend(response.items) if len(response.items) < page_size: break page += 1

2. Cache Component Metadata

# Python import functools import time @functools.lru_cache(maxsize=1000) def get_agent_details(agent_id: str, cache_age: int = 3600): """Cache agent details for 1 hour""" return client.get_agent(agent_id)

3. Use Bulk Operations

# Python # Instead of multiple individual calls for skill_id in skill_ids: client.install_skill(skill_id, ...) # Use bulk operation client.bulk_install_skills(skill_ids, ...)

4. Monitor Usage

# Python from atom_marketplace import MarketplaceClient client = MarketplaceClient(...) # Check usage stats usage = client.get_usage_stats() print(f"API calls remaining: {usage['rate_limit_remaining']}") print(f"Storage used: {usage['storage_used']}/{usage['storage_limit']}")

Error Handling

Error Response Format

All errors follow consistent format:

{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Rate limit exceeded. Retry after 60 seconds.", "details": { "retry_after": 60, "limit": 10000, "window": "hour" } } }

Common Error Codes

CodeHTTP StatusDescription
RATE_LIMIT_EXCEEDED429Rate limit exceeded
TENANT_NOT_FOUND404Tenant not found
COMPONENT_NOT_FOUND404Component not found
INSUFFICIENT_PERMISSIONS403Insufficient permissions
AGENT_LIMIT_EXCEEDED400Agent limit exceeded
INVALID_CONFIGURATION400Invalid configuration
DEPENDENCY_MISSING400Required dependency missing
PLAN_RESTRICTED403Feature not available for plan
WEBHOOK_VERIFICATION_FAILED400Webhook signature verification failed
FEDERATION_KEY_INVALID401Invalid federation key

Error Handling Examples

# Python from atom_marketplace import MarketplaceClient from atom_marketplace.errors import ( RateLimitError, ComponentNotFoundError, InsufficientPermissionsError ) client = MarketplaceClient(...) try: result = client.install_agent(...) except RateLimitError as e: print(f"Rate limited. Retry after {e.retry_after}s") except ComponentNotFoundError as e: print(f"Component not found: {e.component_id}") except InsufficientPermissionsError as e: print(f"Insufficient permissions: {e.required_permission}") except MarketplaceError as e: print(f"Marketplace error: {e.code} - {e.message}")
// TypeScript import { MarketplaceClient, RateLimitError, ComponentNotFoundError, InsufficientPermissionsError } from '@atom-saas/marketplace-sdk'; const client = new MarketplaceClient(...); try { await client.installAgent(...); } catch (error) { if (error instanceof RateLimitError) { console.log(`Rate limited. Retry after ${error.retryAfter}s`); } else if (error instanceof ComponentNotFoundError) { console.log(`Component not found: ${error.componentId}`); } else if (error instanceof InsufficientPermissionsError) { console.log(`Insufficient permissions: ${error.requiredPermission}`); } else { console.log(`Marketplace error: ${error.code} - ${error.message}`); } }

SDK Reference

Python SDK

Installation:

pip install atom-marketplace

Initialization:

from atom_marketplace import MarketplaceClient client = MarketplaceClient( base_url="https://atom-saas.fly.dev/api", tenant_id="your-tenant-id", api_token="your-api-token" )

Key Methods:

  • list_agents(marketplace_type, capability, min_rating) - List agents
  • get_agent(agent_id) - Get agent details
  • publish_agent(...) - Publish agent to marketplace
  • install_agent(agent_id, ...) - Install agent
  • rate_skill(skill_id, rating) - Rate skill
  • create_webhook(url, events, secret) - Create webhook
  • delete_webhook(webhook_id) - Delete webhook

TypeScript SDK

Installation:

npm install @atom-saas/marketplace-sdk

Initialization:

import { MarketplaceClient } from '@atom-saas/marketplace-sdk'; const client = new MarketplaceClient({ baseUrl: 'https://atom-saas.fly.dev/api', tenantId: 'your-tenant-id', apiToken: 'your-api-token' });

Key Methods:

  • listAgents(options) - List agents
  • getAgent(agentId) - Get agent details
  • publishAgent(options) - Publish agent to marketplace
  • installAgent(agentId, options) - Install agent
  • rateSkill(skillId, rating) - Rate skill
  • createWebhook(options) - Create webhook
  • deleteWebhook(webhookId) - Delete webhook

Testing Your Integration

Test Environment

ATOM provides test endpoints for development:

# Test base URL https://atom-saas.fly.dev/api/test # Test authentication curl -X POST "https://atom-saas.fly.dev/api/test/auth/login" \ -H "X-Test-Secret: test-secret-key" \ -H "Content-Type: application/json" \ -d '{"email": "test@example.com", "password": "testpassword"}'

Test Credentials

  • Test Secret: test-secret-key
  • Test Tenant: test-tenant-id
  • Test API Token: Obtain via test login endpoint

Testing Checklist

  • Authentication works with API token
  • Can list marketplace components
  • Can publish test component to private marketplace
  • Can install component from marketplace
  • Webhook receives events correctly
  • Rate limiting is handled properly
  • Errors are caught and handled
  • Pagination works for large lists

Integration Tests

# Python import pytest from atom_marketplace import MarketplaceClient @pytest.fixture def client(): return MarketplaceClient( base_url="https://atom-saas.fly.dev/api/test", tenant_id="test-tenant-id", api_token="test-api-token" ) def test_list_agents(client): agents = client.list_agents(marketplace_type="public") assert len(agents) > 0 assert agents[0]["id"] is not None def test_install_agent(client): result = client.install_agent( agent_id="test-agent", target_tenant_id="test-tenant-id" ) assert result["status"] == "installed"
// TypeScript import { MarketplaceClient } from '@atom-saas/marketplace-sdk'; describe('Marketplace Integration', () => { const client = new MarketplaceClient({ baseUrl: 'https://atom-saas.fly.dev/api/test', tenantId: 'test-tenant-id', apiToken: 'test-api-token' }); test('list agents', async () => { const agents = await client.listAgents({ marketplaceType: 'public' }); expect(agents.length).toBeGreaterThan(0); expect(agents[0].id).toBeDefined(); }); test('install agent', async () => { const result = await client.installAgent('test-agent', 'test-tenant-id'); expect(result.status).toBe('installed'); }); });

Additional Resources


Changelog

v13.0 (2026-04-05)

  • Initial developer guide release
  • Marketplace API integration documentation
  • Federation protocol documentation
  • SDK reference (Python, TypeScript)
  • Webhook integration guide
  • Rate limiting and best practices