# Creatopy API Documentation

## Table of Contents
1. [Authentication](#authentication)
2. [Installation](#installation)
3. [Core Concepts](#core-concepts)
4. [API Endpoints](#api-endpoints)
5. [Resources](#resources)
6. [Error Handling](#error-handling)
7. [Best Practices](#best-practices)
8. [Examples](#examples)

## Authentication

### Getting Started
To use the Creatopy API, you'll need:
- An API key (Developer Token)
- A Client ID
- A User Token

```python
import requests
import json

class CreatopyAPI:
    BASE_URL = "https://api.creatopy.com/v2"
    
    def __init__(self, api_key, client_id):
        self.api_key = api_key
        self.client_id = client_id
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Client-Id": client_id,
            "Content-Type": "application/json"
        }
```

### Authentication Flow

```python
def authenticate(self):
    endpoint = f"{self.BASE_URL}/authenticate"
    response = requests.post(
        endpoint,
        headers=self.headers
    )
    if response.status_code == 200:
        self.user_token = response.json()["token"]
        self.headers["User-Token"] = self.user_token
        return True
    return False
```

## Installation

```bash
pip install requests
```

## Core Concepts

### Projects
Projects are the top-level organizational unit in Creatopy.

```python
def get_projects(self):
    endpoint = f"{self.BASE_URL}/projects"
    response = requests.get(
        endpoint,
        headers=self.headers
    )
    return response.json()

def create_project(self, name, description=""):
    endpoint = f"{self.BASE_URL}/projects"
    payload = {
        "name": name,
        "description": description
    }
    response = requests.post(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

### Designs
Designs are the individual creative assets within projects.

```python
def get_designs(self, project_id):
    endpoint = f"{self.BASE_URL}/projects/{project_id}/designs"
    response = requests.get(
        endpoint,
        headers=self.headers
    )
    return response.json()

def create_design(self, project_id, design_data):
    endpoint = f"{self.BASE_URL}/projects/{project_id}/designs"
    response = requests.post(
        endpoint,
        headers=self.headers,
        json=design_data
    )
    return response.json()
```

## API Endpoints

### Projects API

#### List Projects
```python
def list_projects(self, page=1, per_page=20):
    endpoint = f"{self.BASE_URL}/projects"
    params = {
        "page": page,
        "per_page": per_page
    }
    response = requests.get(
        endpoint,
        headers=self.headers,
        params=params
    )
    return response.json()
```

#### Get Project Details
```python
def get_project(self, project_id):
    endpoint = f"{self.BASE_URL}/projects/{project_id}"
    response = requests.get(
        endpoint,
        headers=self.headers
    )
    return response.json()
```

#### Update Project
```python
def update_project(self, project_id, data):
    endpoint = f"{self.BASE_URL}/projects/{project_id}"
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=data
    )
    return response.json()
```

#### Delete Project
```python
def delete_project(self, project_id):
    endpoint = f"{self.BASE_URL}/projects/{project_id}"
    response = requests.delete(
        endpoint,
        headers=self.headers
    )
    return response.status_code == 204
```

### Designs API

#### Create Design
```python
def create_design(self, project_id, template_id, customizations):
    endpoint = f"{self.BASE_URL}/projects/{project_id}/designs"
    payload = {
        "template_id": template_id,
        "customizations": customizations
    }
    response = requests.post(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

#### Get Design Details
```python
def get_design(self, project_id, design_id):
    endpoint = f"{self.BASE_URL}/projects/{project_id}/designs/{design_id}"
    response = requests.get(
        endpoint,
        headers=self.headers
    )
    return response.json()
```

#### Update Design
```python
def update_design(self, project_id, design_id, updates):
    endpoint = f"{self.BASE_URL}/projects/{project_id}/designs/{design_id}"
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=updates
    )
    return response.json()
```

#### Delete Design
```python
def delete_design(self, project_id, design_id):
    endpoint = f"{self.BASE_URL}/projects/{project_id}/designs/{design_id}"
    response = requests.delete(
        endpoint,
        headers=self.headers
    )
    return response.status_code == 204
```

### Templates API

#### List Templates
```python
def list_templates(self, page=1, per_page=20, filters=None):
    endpoint = f"{self.BASE_URL}/templates"
    params = {
        "page": page,
        "per_page": per_page
    }
    if filters:
        params.update(filters)
    
    response = requests.get(
        endpoint,
        headers=self.headers,
        params=params
    )
    return response.json()
```

#### Get Template Details
```python
def get_template(self, template_id):
    endpoint = f"{self.BASE_URL}/templates/{template_id}"
    response = requests.get(
        endpoint,
        headers=self.headers
    )
    return response.json()
```

### Assets API

#### Upload Asset
```python
def upload_asset(self, file_path, asset_type):
    endpoint = f"{self.BASE_URL}/assets/upload"
    
    with open(file_path, 'rb') as file:
        files = {'file': file}
        data = {'type': asset_type}
        
        response = requests.post(
            endpoint,
            headers=self.headers,
            files=files,
            data=data
        )
    return response.json()
```

#### List Assets
```python
def list_assets(self, page=1, per_page=20, filters=None):
    endpoint = f"{self.BASE_URL}/assets"
    params = {
        "page": page,
        "per_page": per_page
    }
    if filters:
        params.update(filters)
    
    response = requests.get(
        endpoint,
        headers=self.headers,
        params=params
    )
    return response.json()
```

## Resources

### Working with Images
```python
def modify_image(self, design_id, image_id, modifications):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/images/{image_id}"
    payload = {
        "modifications": modifications
    }
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

### Working with Text
```python
def update_text(self, design_id, text_id, new_text, styling=None):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/text/{text_id}"
    payload = {
        "content": new_text
    }
    if styling:
        payload["styling"] = styling
        
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

## Error Handling

```python
class CreatopyError(Exception):
    def __init__(self, message, status_code=None, response=None):
        self.message = message
        self.status_code = status_code
        self.response = response
        super().__init__(self.message)

def handle_response(self, response):
    if response.status_code >= 400:
        error_data = response.json()
        raise CreatopyError(
            message=error_data.get('message', 'Unknown error'),
            status_code=response.status_code,
            response=response
        )
    return response.json()
```

## Best Practices

### Rate Limiting
```python
import time

class RateLimiter:
    def __init__(self, calls_per_second=10):
        self.calls_per_second = calls_per_second
        self.last_call = 0
        
    def wait(self):
        current_time = time.time()
        time_since_last_call = current_time - self.last_call
        
        if time_since_last_call < (1.0 / self.calls_per_second):
            time.sleep((1.0 / self.calls_per_second) - time_since_last_call)
            
        self.last_call = time.time()
```

### Pagination Helper
```python
def paginate_results(self, endpoint, params=None):
    if params is None:
        params = {}
    
    page = 1
    while True:
        params['page'] = page
        response = requests.get(
            endpoint,
            headers=self.headers,
            params=params
        )
        data = response.json()
        
        for item in data['items']:
            yield item
            
        if page >= data['total_pages']:
            break
            
        page += 1
```

## Examples

### Complete Project Workflow
```python
# Initialize the API client
api = CreatopyAPI(api_key="your_api_key", client_id="your_client_id")

# Authenticate
api.authenticate()

# Create a new project
project = api.create_project(
    name="Marketing Campaign 2024",
    description="Q1 Social Media Campaign"
)

# Get a template
templates = api.list_templates(
    filters={"category": "social-media", "format": "instagram-post"}
)
template_id = templates['items'][0]['id']

# Create a design from template
design = api.create_design(
    project_id=project['id'],
    template_id=template_id,
    customizations={
        "text": [
            {
                "id": "headline",
                "content": "New Product Launch!"
            }
        ],
        "colors": {
            "primary": "#FF5733",
            "secondary": "#33FF57"
        }
    }
)

# Upload an image asset
asset = api.upload_asset(
    file_path="product-image.jpg",
    asset_type="image"
)

# Update design with new image
api.modify_image(
    design_id=design['id'],
    image_id="main_image",
    modifications={
        "source": asset['url'],
        "scale": 1.2,
        "position": {"x": 0, "y": 0}
    }
)

# Export the design
export = api.export_design(
    design_id=design['id'],
    format="png",
    quality="high"
)
```

### Error Handling Example
```python
try:
    project = api.create_project(name="New Project")
except CreatopyError as e:
    if e.status_code == 429:
        print("Rate limit exceeded. Please wait and try again.")
    elif e.status_code == 403:
        print("Authentication failed. Please check your credentials.")
    else:
        print(f"An error occurred: {e.message}")
```

### Batch Processing Example
```python
def batch_create_designs(api, project_id, template_id, variations):
    rate_limiter = RateLimiter(calls_per_second=5)
    results = []
    
    for variation in variations:
        rate_limiter.wait()
        try:
            design = api.create_design(
                project_id=project_id,
                template_id=template_id,
                customizations=variation
            )
            results.append({"status": "success", "design": design})
        except CreatopyError as e:
            results.append({"status": "error", "error": str(e)})
    
    return results
```

This documentation provides a comprehensive overview of the Creatopy API functionality in Python.
# Creatopy API - Design Editing Guide

## Table of Contents
1. [Basic Design Operations](#basic-design-operations)
2. [Text Editing](#text-editing)
3. [Image Manipulation](#image-manipulation)
4. [Layout Management](#layout-management)
5. [Color and Styling](#color-and-styling)
6. [Effects and Animations](#effects-and-animations)
7. [Advanced Editing Features](#advanced-editing-features)
8. [Common Editing Workflows](#common-editing-workflows)

## Basic Design Operations

### Getting a Design for Editing
```python
def get_design_for_editing(self, design_id):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/edit"
    response = requests.get(
        endpoint,
        headers=self.headers
    )
    return response.json()
```

### Saving Design Changes
```python
def save_design_changes(self, design_id, changes):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/save"
    response = requests.post(
        endpoint,
        headers=self.headers,
        json=changes
    )
    return response.json()
```

## Text Editing

### Update Text Content
```python
def update_text_content(self, design_id, text_element_id, new_content):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/elements/{text_element_id}"
    payload = {
        "type": "text",
        "content": new_content
    }
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

### Text Styling
```python
def style_text(self, design_id, text_element_id, styling):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/elements/{text_element_id}/style"
    payload = {
        "font_family": styling.get("font_family"),
        "font_size": styling.get("font_size"),
        "color": styling.get("color"),
        "bold": styling.get("bold", False),
        "italic": styling.get("italic", False),
        "underline": styling.get("underline", False),
        "alignment": styling.get("alignment", "left"),
        "letter_spacing": styling.get("letter_spacing", 0),
        "line_height": styling.get("line_height", 1.2)
    }
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

### Text Animation
```python
def add_text_animation(self, design_id, text_element_id, animation):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/elements/{text_element_id}/animation"
    payload = {
        "type": animation.get("type", "fade"),
        "duration": animation.get("duration", 1000),
        "delay": animation.get("delay", 0),
        "easing": animation.get("easing", "ease-in-out")
    }
    response = requests.post(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

## Image Manipulation

### Upload and Replace Image
```python
def replace_image(self, design_id, element_id, image_file):
    # First upload the image
    upload_endpoint = f"{self.BASE_URL}/assets/upload"
    files = {'file': open(image_file, 'rb')}
    upload_response = requests.post(
        upload_endpoint,
        headers=self.headers,
        files=files
    )
    image_url = upload_response.json()['url']
    
    # Then replace the image in the design
    replace_endpoint = f"{self.BASE_URL}/designs/{design_id}/elements/{element_id}"
    payload = {
        "type": "image",
        "src": image_url
    }
    response = requests.put(
        replace_endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

### Image Adjustments
```python
def adjust_image(self, design_id, image_element_id, adjustments):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/elements/{image_element_id}/adjustments"
    payload = {
        "brightness": adjustments.get("brightness", 0),  # -100 to 100
        "contrast": adjustments.get("contrast", 0),      # -100 to 100
        "saturation": adjustments.get("saturation", 0),  # -100 to 100
        "blur": adjustments.get("blur", 0),             # 0 to 100
        "opacity": adjustments.get("opacity", 100)       # 0 to 100
    }
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

### Image Cropping and Resizing
```python
def crop_image(self, design_id, image_element_id, crop_data):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/elements/{image_element_id}/crop"
    payload = {
        "x": crop_data.get("x", 0),
        "y": crop_data.get("y", 0),
        "width": crop_data.get("width"),
        "height": crop_data.get("height"),
        "maintain_aspect_ratio": crop_data.get("maintain_aspect_ratio", True)
    }
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

## Layout Management

### Element Positioning
```python
def position_element(self, design_id, element_id, position):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/elements/{element_id}/position"
    payload = {
        "x": position.get("x", 0),
        "y": position.get("y", 0),
        "z_index": position.get("z_index", 0),
        "rotation": position.get("rotation", 0)
    }
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

### Element Grouping
```python
def group_elements(self, design_id, element_ids):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/groups"
    payload = {
        "element_ids": element_ids
    }
    response = requests.post(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

## Color and Styling

### Change Background
```python
def set_background(self, design_id, background):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/background"
    payload = {
        "type": background.get("type", "color"),  # color, gradient, or image
        "value": background.get("value"),         # color code or image URL
        "gradient": background.get("gradient", {}) # for gradient type
    }
    response = requests.put(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

### Apply Effects
```python
def apply_effect(self, design_id, element_id, effect):
    endpoint = f"{self.BASE_URL}/designs/{design_id}/elements/{element_id}/effects"
    payload = {
        "type": effect.get("type"),  # shadow, glow, etc.
        "settings": effect.get("settings", {})
    }
    response = requests.post(
        endpoint,
        headers=self.headers,
        json=payload
    )
    return response.json()
```

## Common Editing Workflows

### Complete Text Update Workflow
```python
def update_text_with_styling(api, design_id, text_element_id, new_content, styling):
    # First update the text content
    api.update_text_content(
        design_id=design_id,
        text_element_id=text_element_id,
        new_content=new_content
    )
    
    # Then apply styling
    api.style_text(
        design_id=design_id,
        text_element_id=text_element_id,
        styling=styling
    )
    
    # Save the changes
    api.save_design_changes(
        design_id=design_id,
        changes={"status": "complete"}
    )
```

### Image Replacement and Adjustment Workflow
```python
def replace_and_adjust_image(api, design_id, image_element_id, new_image_path, adjustments):
    # Replace the image
    api.replace_image(
        design_id=design_id,
        element_id=image_element_id,
        image_file=new_image_path
    )
    
    # Apply adjustments
    api.adjust_image(
        design_id=design_id,
        image_element_id=image_element_id,
        adjustments=adjustments
    )
    
    # Save changes
    api.save_design_changes(
        design_id=design_id,
        changes={"status": "complete"}
    )
```

### Usage Examples

```python
# Initialize the API client
api = CreatopyAPI(api_key="your_api_key", client_id="your_client_id")
api.authenticate()

# Example 1: Update text with styling
text_styling = {
    "font_family": "Arial",
    "font_size": 24,
    "color": "#FF5733",
    "bold": True,
    "alignment": "center"
}

update_text_with_styling(
    api,
    design_id="design_123",
    text_element_id="text_456",
    new_content="New Headline Text",
    styling=text_styling
)

# Example 2: Replace and adjust image
image_adjustments = {
    "brightness": 10,
    "contrast": 15,
    "saturation": 5,
    "opacity": 90
}

replace_and_adjust_image(
    api,
    design_id="design_123",
    image_element_id="image_789",
    new_image_path="path/to/new/image.jpg",
    adjustments=image_adjustments
)

# Example 3: Complete design update
def update_complete_design(api, design_id):
    # Update background
    api.set_background(
        design_id=design_id,
        background={
            "type": "gradient",
            "gradient": {
                "type": "linear",
                "start_color": "#FF5733",
                "end_color": "#33FF57",
                "angle": 45
            }
        }
    )
    
    # Update text elements
    api.update_text_content(
        design_id=design_id,
        text_element_id="headline",
        new_content="New Campaign"
    )
    
    # Add effects
    api.apply_effect(
        design_id=design_id,
        element_id="headline",
        effect={
            "type": "shadow",
            "settings": {
                "color": "#000000",
                "blur": 10,
                "offset_x": 2,
                "offset_y": 2,
                "opacity": 0.5
            }
        }
    )
    
    # Save all changes
    api.save_design_changes(
        design_id=design_id,
        changes={"status": "complete"}
    )
```

This documentation provides a comprehensive guide to editing designs using the Creatopy API. Each section includes detailed examples and common workflows to help users understand how to implement various editing features.
# Understanding the Creatopy Editing Flow

## Overview of the Editing Process

The editing process in Creatopy follows a specific flow when integrating with the API. Here's a comprehensive breakdown of how it works from a user's perspective.

## 1. Initial Setup

### Authentication & Access
```python
import requests

class CreatopyEditor:
    def __init__(self, api_key, client_id):
        self.api_key = api_key
        self.client_id = client_id
        self.base_url = "https://api.creatopy.com/v2"
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Client-Id": client_id,
            "Content-Type": "application/json"
        }

# Usage
editor = CreatopyEditor("your_api_key", "your_client_id")
```

## 2. Starting the Editing Process

### A. Loading a Design
When a user wants to edit a design, they first need to load it:

```python
def start_editing_session(self, design_id):
    """
    Initialize an editing session for a specific design
    """
    endpoint = f"{self.base_url}/designs/{design_id}/edit"
    response = requests.post(endpoint, headers=self.headers)
    
    if response.status_code == 200:
        # The editing session is now active
        self.current_design = response.json()
        self.editing_session_id = self.current_design['sessionId']
        return self.current_design
    else:
        raise Exception("Failed to start editing session")
```

## 3. Making Edits

### A. Text Editing
Users can edit text elements in the design:

```python
def edit_text(self, element_id, new_text):
    """
    Update the content of a text element
    """
    if not hasattr(self, 'editing_session_id'):
        raise Exception("No active editing session")
        
    endpoint = f"{self.base_url}/designs/{self.current_design['id']}/elements/{element_id}"
    payload = {
        "sessionId": self.editing_session_id,
        "content": new_text
    }
    
    response = requests.put(endpoint, headers=self.headers, json=payload)
    return response.json()

# Usage Example
editor.edit_text("text_123", "New Headline Text")
```

### B. Image Editing
Users can modify images within the design:

```python
def edit_image(self, element_id, modifications):
    """
    Apply modifications to an image element
    """
    endpoint = f"{self.base_url}/designs/{self.current_design['id']}/elements/{element_id}"
    payload = {
        "sessionId": self.editing_session_id,
        "modifications": modifications
    }
    
    response = requests.put(endpoint, headers=self.headers, json=payload)
    return response.json()

# Usage Example
modifications = {
    "brightness": 10,
    "contrast": 15,
    "crop": {
        "x": 0,
        "y": 0,
        "width": 500,
        "height": 300
    }
}
editor.edit_image("image_123", modifications)
```

## 4. Real-Time Updates

### A. Handling Changes
Changes are processed in real-time:

```python
def apply_changes(self, changes):
    """
    Apply a batch of changes to the design
    """
    endpoint = f"{self.base_url}/designs/{self.current_design['id']}/batch"
    payload = {
        "sessionId": self.editing_session_id,
        "changes": changes
    }
    
    response = requests.post(endpoint, headers=self.headers, json=payload)
    return response.json()

# Usage Example
changes = [
    {
        "elementId": "text_123",
        "type": "text",
        "content": "New Text"
    },
    {
        "elementId": "image_456",
        "type": "image",
        "modifications": {
            "brightness": 10
        }
    }
]
editor.apply_changes(changes)
```

## 5. Saving and Finalizing

### A. Saving Progress
Users can save their progress:

```python
def save_progress(self):
    """
    Save the current state of the design
    """
    endpoint = f"{self.base_url}/designs/{self.current_design['id']}/save"
    payload = {
        "sessionId": self.editing_session_id
    }
    
    response = requests.post(endpoint, headers=self.headers, json=payload)
    return response.json()
```

### B. Finalizing Edits
When editing is complete:

```python
def finish_editing(self):
    """
    Complete the editing session and finalize the design
    """
    endpoint = f"{self.base_url}/designs/{self.current_design['id']}/finish"
    payload = {
        "sessionId": self.editing_session_id
    }
    
    response = requests.post(endpoint, headers=self.headers, json=payload)
    if response.status_code == 200:
        # Clear the editing session
        self.editing_session_id = None
        self.current_design = None
    return response.json()
```

## Complete Editing Flow Example

Here's how a typical editing session works from start to finish:

```python
# Complete workflow example
def edit_design_workflow():
    # Initialize the editor
    editor = CreatopyEditor("your_api_key", "your_client_id")
    
    try:
        # Start editing session
        design = editor.start_editing_session("design_123")
        
        # Make text changes
        editor.edit_text("headline_text", "New Campaign Headline")
        
        # Edit image
        image_modifications = {
            "brightness": 10,
            "contrast": 15
        }
        editor.edit_image("main_image", image_modifications)
        
        # Apply batch changes
        batch_changes = [
            {
                "elementId": "subtitle_text",
                "type": "text",
                "content": "New Subtitle"
            },
            {
                "elementId": "background",
                "type": "background",
                "color": "#FF5733"
            }
        ]
        editor.apply_changes(batch_changes)
        
        # Save progress
        editor.save_progress()
        
        # Finish editing
        editor.finish_editing()
        
    except Exception as e:
        print(f"Error during editing: {str(e)}")
        # Handle error appropriately
```

## Important Considerations

1. **Session Management**
   - Each editing session has a unique ID
   - Sessions timeout after period of inactivity
   - Only one active session per design at a time

2. **Change Tracking**
   - All changes are tracked within the session
   - Changes can be reverted until finalized
   - Batch changes are processed more efficiently

3. **Error Handling**
   - Network errors should be handled gracefully
   - Invalid operations should be caught and reported
   - Session timeouts should be managed

4. **Best Practices**
   - Always finish or cancel editing sessions
   - Save progress regularly
   - Batch related changes together
   - Handle errors appropriately
   - Validate changes before applying them

## User Experience Flow

1. User initiates editing of a design
2. System starts an editing session
3. User makes various edits (text, images, etc.)
4. Changes are applied in real-time
5. Progress is saved periodically
6. User finalizes the design
7. Editing session is closed

This process ensures that all changes are tracked and managed properly while providing a smooth editing experience for the end user.
# Creatopy Implementation Options Guide

## Available Implementation Options

### 1. Embedded Editor (Recommended Approach)
Creatopy provides a pre-built, embeddable editor that you can integrate directly into your application.

```javascript
// Example implementation of the embedded editor
const initCreatopyEditor = (containerId, options) => {
    const editor = new CreatopyEditor({
        container: containerId,
        apiKey: 'your_api_key',
        clientId: 'your_client_id',
        designId: options.designId,
        onSave: (design) => {
            console.log('Design saved:', design);
        },
        onError: (error) => {
            console.error('Editor error:', error);
        }
    });
    
    return editor;
};
```

#### HTML Implementation
```html
<div id="creatopy-editor-container" style="width: 100%; height: 800px;"></div>

<script src="https://editor.creatopy.com/editor.js"></script>
<script>
    document.addEventListener('DOMContentLoaded', () => {
        const editor = initCreatopyEditor('creatopy-editor-container', {
            designId: 'your_design_id'
        });
    });
</script>
```

#### Benefits of Embedded Editor:
- Full-featured editor out of the box
- Maintained and updated by Creatopy
- Handles all complex editing operations
- Built-in UI components
- Responsive design
- Cross-browser compatibility
- Regular updates and improvements
- Built-in undo/redo functionality
- Automatic session management

### 2. Custom Editor Implementation (Advanced/Not Recommended)
You could build your own editor using the API, but this is significantly more complex and not recommended unless you have very specific requirements that the embedded editor cannot meet.

```python
# Example of what you'd need to build (simplified)
class CustomCreatopyEditor:
    def __init__(self):
        self.api_client = CreatopyAPI(api_key="your_key", client_id="your_id")
        self.current_session = None
        self.undo_stack = []
        self.redo_stack = []
        
    def init_editor_ui(self):
        # You would need to build:
        # - Canvas rendering system
        # - Element selection system
        # - Property panels
        # - Tool panels
        # - Layer management
        # - Undo/redo system
        # - Asset management
        # - Text editing interface
        # - Image editing tools
        pass
    
    def handle_user_interaction(self, event):
        # Complex event handling system
        pass
    
    def render_canvas(self):
        # Complex rendering system
        pass
```

## Implementation Comparison

### Embedded Editor vs Custom Implementation

| Feature | Embedded Editor | Custom Implementation |
|---------|----------------|----------------------|
| Development Time | Days | Months/Years |
| Maintenance Required | Minimal | Extensive |
| Feature Completeness | Full | Limited by development resources |
| Updates | Automatic | Manual |
| Browser Compatibility | Handled | Must be implemented |
| Mobile Support | Included | Must be implemented |
| Cost | Included with API | High development costs |
| Customization | Limited to API options | Full control |
| Reliability | High | Depends on implementation |

## Recommended Implementation Steps

### 1. Using the Embedded Editor

```javascript
// 1. Include the Creatopy Editor script
<script src="https://editor.creatopy.com/editor.js"></script>

// 2. Configure the editor
const editorConfig = {
    container: 'editor-container',
    apiKey: 'your_api_key',
    clientId: 'your_client_id',
    designId: 'your_design_id',
    
    // Event handlers
    onReady: () => {
        console.log('Editor is ready');
    },
    onSave: (design) => {
        saveDesignToBackend(design);
    },
    onError: (error) => {
        handleEditorError(error);
    },
    
    // Optional customization
    theme: 'light',
    language: 'en',
    features: {
        layers: true,
        undo: true,
        export: true
    }
};

// 3. Initialize the editor
const editor = new CreatopyEditor(editorConfig);

// 4. Handle editor events
editor.on('elementSelected', (element) => {
    updatePropertyPanel(element);
});

editor.on('designChanged', () => {
    enableSaveButton();
});
```

### 2. Backend Integration

```python
from flask import Flask, request
from creatopy_api import CreatopyAPI

app = Flask(__name__)
creatopy = CreatopyAPI(api_key="your_key", client_id="your_id")

@app.route('/api/designs/<design_id>', methods=['GET'])
def get_design(design_id):
    return creatopy.get_design(design_id)

@app.route('/api/designs/<design_id>/save', methods=['POST'])
def save_design(design_id):
    design_data = request.json
    return creatopy.save_design(design_id, design_data)
```

## Implementation Best Practices

1. **Authentication Management**
```javascript
// Handle authentication tokens securely
const initEditor = async () => {
    try {
        const authToken = await getSecureToken();
        const editor = new CreatopyEditor({
            container: 'editor-container',
            authToken: authToken,
            // other config...
        });
    } catch (error) {
        handleAuthError(error);
    }
};
```

2. **Error Handling**
```javascript
// Implement comprehensive error handling
const handleEditorError = (error) => {
    switch (error.code) {
        case 'AUTH_ERROR':
            refreshAuth();
            break;
        case 'SAVE_ERROR':
            retryWithBackoff();
            break;
        case 'NETWORK_ERROR':
            checkConnectivity();
            break;
        default:
            logError(error);
    }
};
```

3. **Save Management**
```javascript
// Implement auto-save functionality
let saveTimeout;

const setupAutoSave = (editor) => {
    editor.on('designChanged', () => {
        clearTimeout(saveTimeout);
        saveTimeout = setTimeout(() => {
            editor.save();
        }, 30000); // Auto-save after 30 seconds of inactivity
    });
};
```

## Conclusion

The recommended approach is to use Creatopy's embedded editor because:
1. Significantly reduced development time and cost
2. Professional-grade features out of the box
3. Regular updates and improvements
4. Built-in cross-browser compatibility
5. Mobile-ready functionality
6. Professional user interface
7. Maintained by Creatopy's team

Building a custom editor should only be considered if you have very specific requirements that cannot be met by the embedded editor, and you have the resources for a long-term development project.

The API documentation provided earlier is still useful for:
- Backend integration
- Custom workflows
- Automation
- Batch processing
- Backend design manipulation
- Integration with other systems

But for the actual editing interface, the embedded editor is the recommended solution.