> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vinmake.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Files, actions and payments

> Files in Timeline and Folders, the human-action task list, agent-run evidence, and the payment-approval gate on due bills.

# Files, actions and payments

Three small lanes that sit either side of the money path: getting a file into the system, seeing what needs doing, and approving a payment.

## Uploads - `/uploads`

### `POST /uploads`

`multipart/form-data`.

| Field    | Notes                |
| -------- | -------------------- |
| `file`   | the bytes            |
| `source` | defaults to `manual` |

The bytes go to the private storage bucket under `raw-intake/sha256/<prefix>/<digest>`, with the service-role key kept server-side, and a row is recorded so the file appears on the Files screen and is available to the classify flow.

```json theme={null}
{
  "ok": true,
  "upload": {
    "id": "<upload id>",
    "bucket": "documents",
    "object_path": "raw-intake/sha256/<first two hex>/<sha256>",
    "source_sha256": "<64 lowercase hex>"
  }
}
```

The response carries the **full storage linkage** and a server-minted upload authority so a Clerk attachment can adopt this Files row instead of creating a second one for the same bytes.
At the current web and backend source revisions, the web composer preserves the row id, bucket and object path but drops that authority before it builds the attachment metadata.
Because the Clerk requires the authority to adopt the persisted row, the browser handoff is not end-to-end traceable at this boundary.
See [Upload to posted journal entry](/greatbook/technical/upload-to-ledger) for the exact artifact chain and the direct-attachment fallback.

### `GET /uploads/list`, `GET /uploads/timeline`

Every recorded upload, newest first.

### `GET /uploads/folders`

Returns child folders, the placements beneath the selected parent, pagination for each collection, and a separate read-only Drive reconciliation summary.
At the root, truly unfiled uploads remain in `placements`; a missing mirror reports `not_scanned` and never enables browser writes.

<Note>
  The status and classification columns on an upload are owned by the Actions flow, not by this route.
  An upload is a file that exists; what was decided about it is a separate fact with a separate writer.
</Note>

## Human-action worklist - `/actions`

Two sources, deliberately kept apart, because they answer different questions.

| Source                                    | Question                                                                                      |
| ----------------------------------------- | --------------------------------------------------------------------------------------------- |
| `GET /actions/tasks`                      | **what needs a person?** - the human worklist, optionally routed to bookkeeping or accounting |
| `GET /actions/types`, `/actions/pipeline` | **what happened to this file?** - the older per-file classify, triage and tag pipeline        |

### `GET /actions/tasks`

| Query    | Default | Notes                                                            |
| -------- | ------- | ---------------------------------------------------------------- |
| `status` | `open`  | `all` includes closed rows; any single status name filters to it |
| `limit`  | `100`   |                                                                  |

Newest first, org-scoped.

This is the API behind **Audit → Actions**, not the top-level Actions run inbox.

## Agent-run inbox - `/agent-runs`

`GET /agent-runs` and `GET /agent-runs/{run_ref}` retain every user/session-scoped agent run, including a failure created before any workspace exists.
The workspace subroutes expose the linked review state, selection, validation, confirmation, commit and receipts only when the run, workspace, organization, user and server-bound session agree.
A terminal error remains an error; only a legitimate completed run with no proposed change is a no-change outcome.
See [Actions agent-run inbox](/greatbook/features/actions-inbox) for the presentation contract.

### `GET /actions/types`, `GET /actions/pipeline`, `POST /actions/run`

The per-file pipeline over uploads and their recorded actions.
It stays a secondary view rather than the tab's spine, because it describes files rather than work.

## Payments - `/payments`

The human-in-the-loop gate on bills that have come due.

| Route                              | Notes                                    |
| ---------------------------------- | ---------------------------------------- |
| `GET /payments/pending`            | bills due, surfaced as pending approvals |
| `GET /payments/{task_id}/audit`    | the decision trail for one approval      |
| `POST /payments/{task_id}/approve` | approve; rides the gated write-back      |
| `POST /payments/{task_id}/reject`  | close it as refused                      |

Both decisions take the **derived actor**, and every change is recorded in the task event trail.
`task_id` is an integer here, not a uuid.

<Warning>
  This lane is a **payment approval**, not a payment.
  Approving here authorises the write-back; it does not move money on a rail, and it is not what posts the settlement entry.
  The entry a payment produces is on [Payments, rails and treasury](/greatbook/gl/rules-money-movement).
</Warning>

<Note>
  The Payments screen does not print a figure today: its payload genuinely carries both a converted and a native amount, and choosing which to show - and in which currency - is a data decision rather than a formatting one.
  It is left blank rather than labelled wrongly.
  That is the same rule as the `base_currency` requirement on [the ledger routes](/greatbook/api/ledger): money is labelled with the currency it is actually in, or not printed.
</Note>

## Connectors and service routes

These routes describe code boundaries only.
Connector credentials and trust are not activated, no working external connector is claimed, and the QuickBooks redirect pair cannot create a connection in the current migration.

| Route                                      | Notes                                                                                                                                                |
| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /ok`                                  | liveness; open                                                                                                                                       |
| `GET /connectors`                          | the registry, each connector's latest probe status, and the credential ask-list                                                                      |
| `POST /connectors/{connector_id}/check`    | re-run one connector's probe                                                                                                                         |
| `POST /connectors/check-all`               | re-run every probe, concurrently                                                                                                                     |
| `GET /connectors/qbo/connect`, `/callback` | open redirect boundaries only; the current migration creates no OAuth client and activates no trusted binding, so they do not establish a connection |
| `POST /cache/invalidate`                   | drop the aggregate-endpoint cache                                                                                                                    |

**No secrets are stored by this service.**
Credentials are read from the environment; an unconfigured connector reports `not_configured` and appears on the ask-list with the exact variable names it is missing, per field.

## Where it is enforced

| Concern                                     | Code                                              |
| ------------------------------------------- | ------------------------------------------------- |
| uploads and their storage linkage           | `langgraph_chat/devcenter/uploads_api.py`         |
| the agent task list and the file pipeline   | `langgraph_chat/devcenter/actions_api.py`         |
| the "is this real work?" gate, in the graph | `langgraph_chat/agents/common/action_required.py` |
| payment approvals and their trail           | `langgraph_chat/devcenter/payments_api.py`        |
| the connector registry and its probes       | `devcenter/registry.py`, `health.py`              |

## The test that would fail if it broke

`langgraph_chat/devcenter/tests/test_actions_tasks_api.py` for the task list's status filtering, and `test_chat_upload_to_files_tab.py` for the one-upload-one-row linkage.

## Related

* [Upload a document](/greatbook/guides/upload-a-document) - the same flow in the UI
* [Upload to posted journal entry](/greatbook/technical/upload-to-ledger) - storage, extraction, mapping, both human gates and the ledger write
* [The review inbox](/greatbook/guides/review-inbox) - where an uploaded document goes next
* [Intake and the posting gate](/greatbook/api/intake) - the gates that follow
* [Settlement, rails and the AP/AR spine](/greatbook/capabilities/subledgers/settlement) - what a payment actually records
