# Object Storage Blob store backed by Cloudflare R2. Upload via the edge proxy (authenticated), read directly via permanent public URL (no key). ## Prerequisites Provision this resource before use. Edge requests without provisioning will error. ### Provision curl -s -X POST https://cohesivity.ai/api/resources/object-storage \ -H "Authorization: Bearer " ### Delete curl -s -X DELETE https://cohesivity.ai/api/resources/object-storage \ -H "Authorization: Bearer " **Important:** Provision this resource now, before building or running the application. Provisioning is the agent's job, not the application's. ## Common Mistakes - **Using the original filename for download/delete.** Upload adds a random hash to the filename for security (e.g., `cat.jpg` → `cat-a3f8b2c1d4e5f6g7.jpg`). Always use the `path` returned by the upload response, not the original filename. - **Putting `?key=` URLs in browser-visible HTML.** Never use ``. Use the `url` from the upload response instead — it's a permanent public link with no key. - **Trying to GET via the edge proxy.** Reads go directly via the `url` returned by upload. The edge proxy only handles PUT (upload) and DELETE. > **Server-side only.** `coh_application_key` is a secret. Call this from your `vercel-hosting` API routes, `cloudflare-workers`, or your own server tier — never from a browser, mobile app, or other client-side code. See the canonical key-secrecy directive in `.cohesivity` for details. **CORS:** edge endpoints set `Access-Control-Allow-Origin: *` so a server-side proxy can be hit from any origin (the proxy itself stays on your server tier; only the response is browser-visible). **Upload response:** `{ ok, path, url, requested_path, path_was_mutated }`. `requested_path` echoes the raw input you sent; `path` is the stored hashed key (which is what you must persist for DELETE / DB indexing). `path_was_mutated` is always `true` for PUT today because every upload gets a random hash suffix — the field is wire-stable for callers that want a single check rather than comparing strings. ## How It Works Object storage is a blob store: write by path, read by path. 1. **Upload** via the edge proxy (authenticated): `PUT /edge/object-storage/?key=` 2. Response returns `{ok, path, url}` — `path` has a random hash suffix, `url` is a permanent public link 3. **Store `path`** in your database alongside your data — this is your file index 4. **Read** using the `url` directly (e.g., ``) — served from Cloudflare's CDN, no key, no proxy 5. **Delete** via the edge proxy (authenticated): `DELETE /edge/object-storage/?key=` ## Upload PUT https://cohesivity.ai/edge/object-storage/?key= Content-Type: image/jpeg Body: Response: { "ok": true, "path": "photos/cat-a3f8b2c1d4e5f6g7.jpg", "url": "https://storage.cohesivity.ai//photos/cat-a3f8b2c1d4e5f6g7.jpg", "requested_path": "photos/cat.jpg", "path_was_mutated": true } - `path` — the stored filename (with random hash). Use this for DELETE and store it in your database. - `url` — permanent public URL. Use this in ``, ``, etc. Served from Cloudflare's CDN. - `requested_path` — the raw path you sent, echoed back for confirmation/logging. - `path_was_mutated` — `true` whenever the stored `path` differs from `requested_path` (always today, since every upload gets a hash suffix). Lets agents detect mutation in one boolean check rather than diffing strings. - Content-Type is preserved: whatever you set on upload is served on read. ## Delete DELETE https://cohesivity.ai/edge/object-storage/?key= Use the `path` from the upload response (the hashed filename). ## Behavior - **Filenames get a random hash suffix.** `photos/cat.jpg` becomes `photos/cat-a3f8b2c1d4e5f6g7.jpg`. This makes URLs unguessable — knowing the original filename is not enough to access the file. - **Reads go direct to CDN.** The `url` from upload points to Cloudflare's CDN. No Cohesivity proxy, no key in the URL. - **Blob store model.** Upload returns the file path — store it in your database alongside your data. This is your file index, just like any CDN or blob store. - **Path rules:** no `..` (directory traversal blocked); leading/trailing slashes are trimmed; backslashes are normalized to `/`. Paths are case-sensitive. - **Upload size:** governed by the Launch Rate Limits section below and the account bucket/fluid model. - **Egress:** Free — no bandwidth charges for reads. - **For images:** compress and resize on the client before uploading. Recommended: max 1200px longest side, JPEG quality 0.8. ## Launch Rate Limits Ephemeral tenants pause as a whole if any authoritative hard cap below is exceeded. Claimed tiers use account-scoped buckets shared across every project owned by the Cohesivity user; OpenAI, Deepgram, and Exa are fluid-only after tier, rate, and concurrency checks; Deepgram has no fixed monthly usage bucket for claimed tiers. **Ephemeral** - uploads: 250 per ephemeral tenant lifetime before claim or expiry - uploaded bytes: 2 GB per ephemeral tenant lifetime before claim or expiry - live storage: 1 GB max total - uploads: 10 per minute **Claimed Free** - live storage: 10 GB max total - uploads: 30 per minute - uploads: 10000 per month - uploaded bytes: 50 GB per month **Claimed Plus** - live storage: 100 GB max total - uploads: 150 per minute - uploads: 100000 per month - uploaded bytes: 500 GB per month **Claimed Pro** - live storage: 500 GB max total - uploads: 750 per minute - uploads: 500000 per month - uploaded bytes: 2500 GB per month ### Notes - Public reads on `storage.cohesivity.ai` bypass the main Worker today. Upload/delete/storage limits above are hard; public read abuse is monitored and coarse-limited separately.