3.7 KiB
3.7 KiB
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)
{
"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:
{
"filename": "3460a8e1-fe19-4371-a735-64078e9923a4.webp"
}
→ Full URL: https://img.kosmi.io/3460a8e1-fe19-4371-a735-64078e9923a4.webp
Implementation Notes
For Go Client
- No authentication needed - This is a public upload endpoint
- Use standard multipart/form-data - Go's
mime/multipartpackage - Set CORS headers:
Origin: https://app.kosmi.ioReferer: https://app.kosmi.io/
- Parse JSON response to get the image URL
- Send the URL to Kosmi chat via the existing WebSocket
sendMessagemutation
Workflow
- Generate room code PNG image (already implemented in
roomcode_image.go) - Upload PNG to
https://img.kosmi.io/via HTTP POST - Parse response to get image URL
- Send message to Kosmi chat with the image URL
- 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.ioCDN - The upload is CORS-protected (only works from
app.kosmi.ioorigin)
Example Implementation (Pseudocode)
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:
- Generate a test room code image
- Upload it to
https://img.kosmi.io/ - Verify we get a URL back
- Send the URL to Kosmi chat
- 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