Guide
What `recent_uploads.status` means
The pending → claimed → expired / oversize state machine on every upload link. Sourced from R2 events, not the client.
5/18/2026 · connect0 · 3 min
Every file connecting into the core moves through a small state machine — this is how you (and the agent) know it actually landed.
Every upload.create_link and upload.write call writes a row to upload_link. That row has a derived status field, surfaced through info's recent_uploads and the dashboard's project pages. The state machine is small but worth understanding because it's how you (and the agent) answer "did the upload work?"
The four states
| Status | Meaning |
|---|---|
pending | Link issued, R2 hasn't reported a PUT yet. Either the user hasn't uploaded, or the upload landed within the last few seconds and the event hasn't propagated through the queue. |
claimed | R2 fired an event saying bytes landed at the target key. This is the only signal that flips the row to claimed — a hostile client can't fake it. |
expired | The link's expires_at passed and no claim ever arrived. The audit row stays around for forensics; the URL itself stopped working. |
oversize | R2 reported more bytes than the link's content_length declared. The bytes are in R2 (we don't reject after-the-fact), but the row is flagged for an operator to investigate. |
Why claim is R2-driven, not client-driven
The browser-helper page sees a successful PUT and could just call back to the server saying "done." We don't trust that signal — a buggy or malicious client can lie. Instead, R2 publishes an event-notification to a Cloudflare Queue, an internal Worker reads it, and that Worker POSTs to apps/api with an HMAC-signed payload. The audit ledger reflects what Cloudflare actually saw.
Side effect: there's a delay between "PUT succeeded" and "row flips to claimed." Typically a few seconds; occasionally longer when Cloudflare's event pipeline is heavy. The UI shows "uploaded — confirming with R2" during that window.
How the agent should use it
After an upload-link issuance, the right "did it work?" loop is:
infowith{account_slug, project_slug}set.- Find the link in
current_project.recent_uploads(the most recent matchingtarget_path). - If
status === "claimed", proceed. - If
status === "pending"and the link issuance was < ~30s ago, wait + retry. - If
status === "pending"and > 60s ago, the upload probably didn't happen. Ask the user. - If
status === "oversize", the file is on disk but it's bigger than declared — usually a clue that the agent passedcontent_lengthwrong.
On the dashboard
/a/<account>/projects/<project>/upload has a "Recent uploads" card with the same data plus colour-coded badges. oversize is destructive-tinted because it's the one status that wants human eyes.
Reading the bytes_received column
When status === "claimed", bytes_received is what R2 reported. Compare to content_length (what the agent declared) to spot drift. They should match exactly for the upload.create_link path with content_length set; differ for the no-content-length variant or for upload.write (where the agent computes the bytes itself).
Next steps
Where this fits
This is the Connect everything pillar of connect0 — the core that connects everything your company runs on. The status ledger is how the core proves a file really connected in — sourced from R2, not the client. Start building → · All guides →