> ## Documentation Index
> Fetch the complete documentation index at: https://docs.productflo.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Get started with the ProductFlo API and WebSockets

# ProductFlo API Quickstart

This guide will help you get started with the ProductFlo API, focusing on the real-time WebSocket functionality. You'll learn how to connect, authenticate, send messages, and handle responses.

## Authentication

Before using the API, you need to authenticate:

```javascript theme={null}
// Get an authentication token
const response = await fetch('https://api.productflo.io/auth/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'your-email@example.com',
    password: 'your-password',
  }),
});

const { token } = await response.json();
```

## WebSocket Connection

### Connect to the WebSocket API

```javascript theme={null}
// Connect with authentication token
const socket = new WebSocket(`wss://api.productflo.io/ws?token=${token}`);

// For anonymous connections (no authentication)
const socket = new WebSocket('wss://api.productflo.io/ws');

// Handle connection events
socket.onopen = () => {
  console.log('Connected to ProductFlo WebSocket API');
};

socket.onclose = (event) => {
  console.log('Disconnected from ProductFlo WebSocket API', event.code, event.reason);
};

socket.onerror = (error) => {
  console.error('WebSocket error:', error);
};
```

### Handle Messages

```javascript theme={null}
socket.onmessage = (event) => {
  const message = JSON.parse(event.data);
  
  // Handle different message types
  switch(message.type) {
    case 'chat':
      handleChatMessage(message);
      break;
    case 'system':
      handleSystemMessage(message);
      break;
    case 'error':
      handleErrorMessage(message);
      break;
    case 'presence':
      handlePresenceUpdate(message);
      break;
    default:
      console.log('Received message:', message);
  }
};

function handleChatMessage(message) {
  console.log(`${message.data.sender}: ${message.data.message}`);
}

function handleSystemMessage(message) {
  console.log(`System: ${message.data.message}`);
}

function handleErrorMessage(message) {
  console.error(`Error (${message.data.code}): ${message.data.message}`);
}

function handlePresenceUpdate(message) {
  console.log(`User ${message.data.user_id} is now ${message.data.status}`);
}
```

## Send Messages

### Join a Room

```javascript theme={null}
socket.send(JSON.stringify({
  type: 'join',
  room_id: 'product-123'
}));
```

### Send a Chat Message

```javascript theme={null}
socket.send(JSON.stringify({
  type: 'chat',
  room_id: 'product-123',
  task: 'direct_chat',
  data: {
    message: 'Hello team!',
    sender: 'user-456'
  }
}));
```

### Request AI-Generated Content

```javascript theme={null}
socket.send(JSON.stringify({
  type: 'chat',
  task: 'image_generation',
  data: {
    message: 'Generate a 3D model of a smartphone with a foldable display',
    sender: 'user-456',
    product_id: 'product-123'
  }
}));
```

## Advanced Usage

### Room-Based Communication

ProductFlo uses rooms for efficient message routing:

```javascript theme={null}
// Join a room
socket.send(JSON.stringify({
  type: 'join',
  room_id: 'product-123'
}));

// Send a message to the room
socket.send(JSON.stringify({
  type: 'chat',
  room_id: 'product-123',
  data: {
    message: 'Let\'s discuss the new design',
    sender: 'user-456'
  }
}));

// Leave a room
socket.send(JSON.stringify({
  type: 'leave',
  room_id: 'product-123'
}));
```

### Presence Updates

Track when users come online or go offline:

```javascript theme={null}
// Update your status
socket.send(JSON.stringify({
  type: 'presence',
  data: {
    status: 'online',  // 'online', 'away', 'busy', 'offline'
    last_active: new Date().toISOString()
  }
}));
```

### Error Handling

Handle errors from the WebSocket API:

```javascript theme={null}
socket.onmessage = (event) => {
  const message = JSON.parse(event.data);
  
  if (message.type === 'error') {
    const { code, message: errorMessage, details } = message.data;
    
    switch (code) {
      case 'INVALID_FORMAT':
        console.error('The message format is invalid:', errorMessage);
        break;
      case 'VALIDATION_ERROR':
        console.error('Message validation failed:', details.errors);
        break;
      case 'PROCESSING_ERROR':
        console.error('Server failed to process the message:', errorMessage);
        break;
      default:
        console.error(`Error (${code}):`, errorMessage);
    }
  }
};
```

## Framework-Specific Examples

<Tabs>
  <Tab title="React">
    ```jsx theme={null}
    import { useEffect, useState } from 'react';

    function WebSocketComponent() {
      const [socket, setSocket] = useState(null);
      const [messages, setMessages] = useState([]);
      
      useEffect(() => {
        // Create WebSocket connection
        const ws = new WebSocket('wss://api.productflo.io/ws');
        
        ws.onopen = () => {
          console.log('Connected to WebSocket');
          setSocket(ws);
        };
        
        ws.onmessage = (event) => {
          const message = JSON.parse(event.data);
          setMessages((prev) => [...prev, message]);
        };
        
        ws.onclose = () => {
          console.log('Disconnected from WebSocket');
        };
        
        // Clean up on unmount
        return () => {
          ws.close();
        };
      }, []);
      
      const sendMessage = (text) => {
        if (socket && socket.readyState === WebSocket.OPEN) {
          socket.send(JSON.stringify({
            type: 'chat',
            room_id: 'react-room',
            data: {
              message: text,
              sender: 'react-user'
            }
          }));
        }
      };
      
      return (
        <div>
          <h1>ProductFlo WebSocket Chat</h1>
          <div>
            {messages.map((msg, index) => (
              <div key={index}>
                {msg.data?.sender}: {msg.data?.message}
              </div>
            ))}
          </div>
          <button onClick={() => sendMessage('Hello from React!')}>
            Send Message
          </button>
        </div>
      );
    }
    ```
  </Tab>

  <Tab title="Vue">
    ```vue theme={null}
    <template>
      <div>
        <h1>ProductFlo WebSocket Chat</h1>
        <div>
          <div v-for="(msg, index) in messages" :key="index">
            {{ msg.data?.sender }}: {{ msg.data?.message }}
          </div>
        </div>
        <button @click="sendMessage('Hello from Vue!')">
          Send Message
        </button>
      </div>
    </template>

    <script>
    export default {
      data() {
        return {
          socket: null,
          messages: []
        };
      },
      mounted() {
        this.socket = new WebSocket('wss://api.productflo.io/ws');
        
        this.socket.onopen = () => {
          console.log('Connected to WebSocket');
        };
        
        this.socket.onmessage = (event) => {
          const message = JSON.parse(event.data);
          this.messages.push(message);
        };
        
        this.socket.onclose = () => {
          console.log('Disconnected from WebSocket');
        };
      },
      beforeUnmount() {
        if (this.socket) {
          this.socket.close();
        }
      },
      methods: {
        sendMessage(text) {
          if (this.socket && this.socket.readyState === WebSocket.OPEN) {
            this.socket.send(JSON.stringify({
              type: 'chat',
              room_id: 'vue-room',
              data: {
                message: text,
                sender: 'vue-user'
              }
            }));
          }
        }
      }
    };
    </script>
    ```
  </Tab>

  <Tab title="Angular">
    ```typescript theme={null}
    import { Component, OnInit, OnDestroy } from '@angular/core';

    @Component({
      selector: 'app-websocket',
      template: `
        <h1>ProductFlo WebSocket Chat</h1>
        <div>
          <div *ngFor="let msg of messages">
            {{ msg.data?.sender }}: {{ msg.data?.message }}
          </div>
        </div>
        <button (click)="sendMessage('Hello from Angular!')">
          Send Message
        </button>
      `
    })
    export class WebSocketComponent implements OnInit, OnDestroy {
      socket: WebSocket | null = null;
      messages: any[] = [];
      
      ngOnInit() {
        this.socket = new WebSocket('wss://api.productflo.io/ws');
        
        this.socket.onopen = () => {
          console.log('Connected to WebSocket');
        };
        
        this.socket.onmessage = (event) => {
          const message = JSON.parse(event.data);
          this.messages.push(message);
        };
        
        this.socket.onclose = () => {
          console.log('Disconnected from WebSocket');
        };
      }
      
      ngOnDestroy() {
        if (this.socket) {
          this.socket.close();
        }
      }
      
      sendMessage(text: string) {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
          this.socket.send(JSON.stringify({
            type: 'chat',
            room_id: 'angular-room',
            data: {
              message: text,
              sender: 'angular-user'
            }
          }));
        }
      }
    }
    ```
  </Tab>
</Tabs>

## Next Steps

* Explore the [WebSocket API](/api-reference/websockets/introduction) for more details on message types and endpoints
* Learn about [AI communication](/api-reference/websockets/ai-communication) for integrating AI features
* Check out the [real-time communication architecture](/core-concepts/real-time-communication) to understand the underlying technology
