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 Marketplace**Pre-built AI agents with defined capabilities/api/agent-marketplace
**Skill Marketplace**Reusable skill components for agents/api/skill-marketplace
**Canvas Marketplace**Agent workspace templates/api/canvas-marketplace
**Domain Marketplace**Specialized 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
**Unauthenticated**100 requests/hourPer IP
**API Token**10,000 requests/hourPer tenant
**Federation Key**1,000 requests/hourPer federation key
**Admin Key**No 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

  • **API Documentation:** /docs/MARKETPLACE_API.md
  • **Federation Protocol:** /docs/FEDERATION_API.md
  • **Architecture:** /docs/MARKETPLACE_ARCHITECTURE.md
  • **Support:** support@atom-saas.com
  • **Community:** https://community.atom-saas.com

---

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