# Kosmi Image Upload Protocol

## Summary

Kosmi uses a **simple HTTP POST** to upload images, **NOT the WebSocket**. Images are uploaded to a dedicated CDN endpoint.

## Upload Endpoint

```
POST https://img.kosmi.io/
```

## Request Details

### Method
`POST`

### Headers
```
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary...
Origin: https://app.kosmi.io
Referer: https://app.kosmi.io/
```

**Important:** No authentication required! The endpoint accepts anonymous uploads.

### Request Body
Standard `multipart/form-data` with a single field:

```
------WebKitFormBoundary...
Content-Disposition: form-data; name="file"; filename="blurt.jpg"
Content-Type: image/jpeg

[binary image data]
------WebKitFormBoundary...--
```

### CORS
The endpoint has CORS enabled for `https://app.kosmi.io`:
```
Access-Control-Allow-Origin: https://app.kosmi.io
```

## Response

### Status
`200 OK`

### Headers
```
Content-Type: application/json
Access-Control-Allow-Origin: https://app.kosmi.io
```

### Response Body (CONFIRMED)
```json
{
  "filename": "8d580b3a-905d-4bc9-909b-ccc6743edbdc.webp"
}
```

**Note:** The response contains only the filename, not the full URL. The full URL must be constructed as:
```
https://img.kosmi.io/{filename}
```

Example:
```json
{
  "filename": "3460a8e1-fe19-4371-a735-64078e9923a4.webp"
}
```
→ Full URL: `https://img.kosmi.io/3460a8e1-fe19-4371-a735-64078e9923a4.webp`

## Implementation Notes

### For Go Client

1. **No authentication needed** - This is a public upload endpoint
2. **Use standard multipart/form-data** - Go's `mime/multipart` package
3. **Set CORS headers**:
   - `Origin: https://app.kosmi.io`
   - `Referer: https://app.kosmi.io/`
4. **Parse JSON response** to get the image URL
5. **Send the URL to Kosmi chat** via the existing WebSocket `sendMessage` mutation

### Workflow

1. Generate room code PNG image (already implemented in `roomcode_image.go`)
2. Upload PNG to `https://img.kosmi.io/` via HTTP POST
3. Parse response to get image URL
4. Send message to Kosmi chat with the image URL
5. Kosmi will automatically display the image as a thumbnail

### Security Considerations

- The endpoint is public (no auth required)
- Files are likely rate-limited or size-limited
- Images are served from `img.kosmi.io` CDN
- The upload is CORS-protected (only works from `app.kosmi.io` origin)

## Example Implementation (Pseudocode)

```go
func UploadImageToKosmi(imageData []byte, filename string) (string, error) {
    // Create multipart form
    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    
    // Add file field
    part, err := writer.CreateFormFile("file", filename)
    if err != nil {
        return "", err
    }
    part.Write(imageData)
    writer.Close()
    
    // Create request
    req, err := http.NewRequest("POST", "https://img.kosmi.io/", body)
    if err != nil {
        return "", err
    }
    
    // Set headers
    req.Header.Set("Content-Type", writer.FormDataContentType())
    req.Header.Set("Origin", "https://app.kosmi.io")
    req.Header.Set("Referer", "https://app.kosmi.io/")
    
    // Send request
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()
    
    // Parse response
    var result struct {
        URL string `json:"url"`
    }
    json.NewDecoder(resp.Body).Decode(&result)
    
    return result.URL, nil
}
```

## Testing

To test the upload, we can:
1. Generate a test room code image
2. Upload it to `https://img.kosmi.io/`
3. Verify we get a URL back
4. Send the URL to Kosmi chat
5. Verify the image displays as a thumbnail

## References

- HAR capture: `image_upload_HAR-sanitized.har` (lines 3821-4110)
- Upload request: Line 3910-4018
- Upload response: Line 4019-4092

