docs(storage): connected storage overview, Cloudflare R2, Amazon S3 and Supabase - #88
Merged
Conversation
First page of a new Storage group, sitting between Concepts and Jobs.
One page per provider rather than one combined Connect storage page. The
three flows share almost nothing: R2 is a token, S3 is a CloudFormation
stack, Supabase is OAuth. Combining them would be three how-tos in a trench
coat, which the Diatoxis one-word test exists to catch.
Screenshots come from the committed capture spec in the monorepo rather than
being taken by hand, so a UI change is one command instead of an afternoon of
re-cropping. The argument for that is a shot in this same batch that went
stale within a day of being taken.
Every claim traced to code, not to memory. The path tokens are the four in
path-template.ts, the default template is rendobar/{job_id} from the same
file, and the conflict suffix is the last six characters of the job id
because that is what the code does.
The two Next cards point at pages that exist. Amazon S3 and Deliveries are
next, and the cards swap when they land rather than shipping two 404s now.
Hero above the opening sentence. It is visual context rather than preamble: the first line still states what the page gets you, which is the rule the banner could easily have broken. Links added where a reader's next question actually is, not in a pile at the bottom. The S3-compatibility and API-token links sit on the sentence that raises them. A refusal at Connect now names destination_denied and points at the error codes page, because that is the one failure this flow produces and the page previously left the reader to guess. Four external links, all verified 200 rather than recalled. The R2 pricing one is there for a reason worth stating: R2 charges no egress fee, which is the usual reason someone delivers here instead of to S3. mint validate passes and broken-links reports nothing for this page. The three it does report are in captions/animate, captions/burn and compose, which this branch never touched.
The opening was 'Connect an R2 bucket and jobs can read inputs from it and write outputs back', which buries the verb behind a setup clause and uses 'and' twice. Now it leads with what happens: jobs read inputs from your R2 bucket and write outputs back to it. The prereq moves to the second sentence, which is where the rulebook puts it. Hero is the new diagram. hero-all.png lands too, unused until the storage overview page exists, because it comes out of the same run and splitting that across two commits would mean regenerating to get it. mint validate passes.
…he R2 page The hero diagram used dashed lines with triangle heads and two-word emerald labels, which is the house style of every generated diagram. Solid hairlines, one word each, and the whole diagram scaled up to fill the frame. The job example was a bare compress.target JSON blob. It is now a CodeGroup with the SDK first and cURL second, running a real ffmpeg command that reads from the bucket and delivers back to it, plus the deliveries[] shape a completed job carries.
A folder, not a path template. The tokens have their own table two sections
down, so using them in the first example makes the reader parse
{date}/{source_name}.{ext} before they know what any of it means.
Also repairs the cURL line continuations, which a scripted edit had eaten.
Audited against the docs rulebook. Six fixes:
- The first code block sat three screens down, behind the whole Cloudflare
console walkthrough. The storage:// shape now appears in the opening, so
someone who landed here searching for it does not have to scroll.
- Dropped "about two minutes". Time-to-value claims are banned.
- The page used storage://demo-bucket without ever saying the id is yours to
pick or that it must match [a-z0-9-]{2,40}. You could not construct the URI
from the page.
- Captioned the three bare Frames. Images are opaque to the docs Assistant,
so an uncaptioned one is invisible to it.
- Two sections opened with orphan pronouns ("change any of this") which do
not survive being read as a standalone chunk.
- Cut "Cloudflare's own docs": three of its four links were already inline.
Adds a table of the seven delivery failure reasons, sourced from
DELIVERY_REASONS and the messages in adapter.ts. That is what people arrive
needing when a delivery failed, and the page previously had one line on it.
…oth key types Three changes, all from review: The pseudo-format block at the top was not real syntax. Anyone copying it had nothing that runs. Replaced with the actual SDK/cURL example, moved up to the first screen, so the page leads with the thing you are working toward. The page started in the Cloudflare console, which is backwards. Nobody arrives having decided to make a token; they arrive in Rendobar wanting to connect a bucket. It now starts at Storage -> Connect Storage, meets the Key type switch, and goes to Cloudflare only because the dialog asked for something. The R2 dialog accepts two credentials and the page documented one. Adds the access key and secret path (account id, key, secret) with its own screenshot, and says what both paths have in common: a stored S3 pair, with the token path deriving one and then dropping the token. Also gives the mental model a home in the opening (your media stays in your bucket, one credential, one id) instead of leaving it implicit.
…own page Adopts the reviewed structure: a "what you'll do" roadmap, numbered steps, a text flow diagram, and template-to-rendered examples instead of bare templates. Rotation and revocation get their own headings, since they are different tasks with different consequences. Delivery configuration moves to storage/deliveries. None of it is R2-specific (output path, tokens, name conflicts, default destination, public URLs are identical on S3, Supabase and S3-compatible), so keeping it here meant writing it four times and letting three copies drift. Not adopted from the draft, with reasons: - /v1/jobs: the API is unversioned, the path would 404 - "about two minutes": time-to-value claims are banned - four H1s: Mintlify renders the H1 from frontmatter, these duplicate it - blockquote callouts and bare relative-path images: loses the Mintlify components and leaves the images unreadable to the docs Assistant - it also dropped the second key type and the delivery failure table Corrected one invention of my own on the new page: "By job id" is not a preset. The dialog offers By date, Flat and Custom template only.
Storage now has a hub and spokes. /storage carries everything true of every connection: the model and the flow diagram, the storage:// scheme, the id and why it exists, the four access checks, what gets stored and how it is sealed, rotation, revocation, the seven delivery failure reasons, and the client.storage.* surface. The R2 page keeps a complete walkthrough so nobody has to read two pages to connect a bucket, but only the parts that are actually about R2: the two key types, the Cloudflare console, the paste behaviour, and R2-only notes on r2.dev domains, jurisdictions and egress. 857 -> 633 words. The failure table was the clearest case for the split. Not one of its seven rows is provider-specific, so leaving it on the connector pages meant writing it four times and letting three copies drift. Amazon S3, Supabase and S3-compatible pages follow the same shape. The provider table on /storage names them without linking, since those pages do not exist yet.
Folds delivery settings back into /storage. The separate page was justified by avoiding duplication across four connectors, and /storage existing already solves that, so it was a page boundary with nothing behind it. It also split one topic in half: the delivery failure reasons sat on the connections page while the deliveries[] shape they appear in sat on the other. The shape is now a concepts page and a group of integration pages, each of which carries only what is true of its own provider. storage/deliveries was never pushed, so no redirect is needed.
…d ones Three things on that page needed showing rather than describing, and only one of them had a picture. The job flow was an ASCII block. It is now four steps left to right, with the signing step given its own node because "nothing is public" is the part people do not believe until they see where the signature happens. The storage:// anatomy had no diagram at all, and which segment is the id you chose is the single most common confusion. It is now labelled under the string. The path template was a before/after code block. It now maps each token to the value it became, then shows the key, so nobody has to diff two strings by eye. The first cut of the template diagram column-aligned the two keys, which drifted the literal separators apart and made the rendered key read as fragments. Both keys are whole now and the mapping carries the correspondence.
…style guide Rewritten from scratch after reading developers.cloudflare.com/style-guide and several R2 pages, rather than approximating the register from memory. Applied from their documented rules: - Second-person imperative with location before action, and Select for UI controls. No please, no directional language. - Complete sentences in steps, one action per step. - Numbered section headings on the multi-procedure page, capped near ten steps. - Warnings reserved for security or breaking behavior, one aside per section. - Closing order of verification, irreversible step, optional block, next steps. - The feature defined plainly up front, with the default behavior stated. Removed the constructions that prompted the rewrite: contrastive imperatives (Start in Rendobar, not in Cloudflare), aphoristic closers (This is the reason the id exists), and mid-procedure editorialising (Not Admin). Paragraphs now state and stop rather than building to a line. Corrected two UI labels I had invented: the actions menu reads Test Connection and Replace Keys, not Test and Rotate.
…ecycle A completed job with a destination returns two URLs for the same content and the page did not distinguish them. output.file.url is a Rendobar URL that expires at output.expiresAt; the url in deliveries[] is the copy in the customer's own bucket, which does not expire. That difference is the reason to set a destination at all. Also states that deliveries resolve asynchronously: a job can be complete with its output populated while a delivery is still pending, and a failed delivery does not change the job status. Names the job.delivered and job.delivery_failed webhooks and the retry route.
…event family deliveries[].storage holds a connection id, so it is storageId. Renamed while the feature is unmerged and the change is still free. Adds a Delivery events section: what job.completed does and does not promise, the three delivery events, and that job.deliveries_settled is the one to wait on and the only one a per-job callback.url receives.
Both pages said storage://demo-bucket/exports writes exports/{job_id}.{ext}.
It does not. Every new connection gets the By date template, a bare id uses
that template, and a folder keeps only the template's file name, so the example
job writes exports/clip.mp4. Adds a table of the three destination forms and
what each writes, and states that Keep both is the default and needs a bucket
that supports conditional writes.
Tightened for reading. The overview lost restated captions, a meta sentence
about what the page covers, the id and credential points each made twice or
three times, and filler lead-ins, and fell from 894 to 838 prose words despite
the new table. The R2 page fell from 694 to 537: its steps are contiguous,
the provider-picker screenshot is gone, and it now warns that deliveries can
still be pending when run() returns. No sentence on either page runs over 25
words.
Section anchors renamed: Delivery settings, Credentials, SDK methods. Internal
links updated and checked with broken-links --check-anchors.
The connection flow was a PNG, which the docs Assistant and the markdown mirrors cannot read, and it drew the output going straight back to the bucket. It now shows the real path: the runner reads through a signed URL, uploads the output to Rendobar storage, and Rendobar writes it to the bucket. diagram-flow.png is removed. The delivery events table becomes a sequence diagram, because what readers need is that destinations resolve independently, which a table cannot show. job.completed is deliberately left out of that diagram: deliveries are enqueued before billing settles and job.completed is sent after, so drawing it first would have been wrong. The prose now says webhooks can arrive in any order and that job.deliveries_settled carries every outcome, so order does not matter. Also corrects Credentials, which said Rendobar stores keys for every connection. A one-click AWS role stores none; Rendobar assumes the role. Both diagrams parse with mermaid 11. mint validate and broken-links pass.
…ation_unavailable
storage/index.mdx is served at /docs/storage, so its canonical is that URL. The check expected /docs/storage/index, a page Mintlify never serves, and failed the storage docs PR.
a-essawy
marked this pull request as ready for review
September 13, 2026 04:29
…them need Existing API keys and OAuth grants predate storage:read and storage:write, so the storage endpoints answer them with INSUFFICIENT_SCOPE. The scopes page lists the new resource and says to create a new key or reconnect. The storage pages are dated the day they go live.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Docs for connected storage: an overview of how connections work, and one page per provider.
/storage): connections, thestorage://URI, the Playground pickers, what happens when a job runs (Mermaid), delivery settings, results, events and errors, credentials, SDK methods.job.deliveries_settledon Callbacks,destinationson Jobs, a Storage section on the SDK page,list_storageon the MCP server page, and storage error codes on Errors.Merge after rendobar/rendobar#682 is deployed to production. These pages describe that release.
Test plan
mint validatepassesmint broken-links --check-anchors: no new broken links (the 3 reported are pre-existing, injobs/captionsandjobs/compose)