Skip to main content

Upload Chat Image

POST 

/v1/chats/upload-image

Phase 95 SA1 — chat textarea image upload (PHASE95/PLAN.md contract).

Accepts a single image (PNG / JPEG / WebP / GIF, max 10 MB) from the chat textarea drag-and-drop or paperclip path (SA2). Persists to object storage under account/<account_id>/chat-images/<uuid>.<ext> and returns a 1-hour presigned GET URL the frontend can attach to the next user message via images: [{ url, objectPath }].

We do server-side PUT rather than the 2-step presigned-PUT flow used by /v1/upload/<folder> for two reasons:

  1. Chat UX wants a single round-trip (drop → upload → attach) — the 2-step flow needs a second fetch from the browser to S3 which adds a round-trip and surfaces CORS pain.
  2. We validate mimetype + size on the server so the LLM provider (Anthropic / OpenAI) never sees malformed payloads. Presigned PUT skips that gate.

The returned URL is intentionally short-lived (3600s). For long-running chats we re-presign via object_service.get_presigned_url(object_path) on render — the object_path round-trip is the source of truth, not the URL itself.

Request

Responses

Successful Response