# Files & Artifacts

S3-style presigned uploads and downloads for managed artifacts over /v1/files.

## Upload

`client.files.upload(input)` is the convenience that orchestrates the S3-style flow: create a presigned delegation (`POST /v1/uploads`), PUT the bytes to the signed URL, then complete it (`POST /v1/uploads/complete`). `path` is required; `sizeBytes` and the `sha256` the verifier requires are computed for you from the bytes. Only contract fields are forwarded (`path`, `title`, `kind`, `mimeType`, `sourceThreadId`, `sourceMessageId`, `metadata`, `expiresInSeconds`); unknown keys are rejected. Requires `files:write`.

```bash
const completed = await client.files.upload({
  bytes: "hello from the SeaChat SDK\n",
  path: "sdk-examples/demo.txt",
  kind: "binary",
});
const fileId = completed.result?.artifact?.id;
```

## Read metadata

`client.files.get(fileId)` (`GET /v1/files/{fileId}`) returns artifact metadata, and `client.files.list(query?)` (`GET /v1/files`) lists artifacts by `prefix`, `kind`, `artifactType`, or `label`. Reads need `seadb:content:read`.

```bash
const meta = await client.files.get(fileId);
const list = await client.files.list({ prefix: "sdk-examples" });
```

## Download

`client.files.content(fileId)` (`GET /v1/files/{fileId}/content`) resolves the bytes. The gateway typically streams them inline (`200`) but may return a signed `302` redirect; the SDK returns `{ url, response }` — `url` is the signed `Location` when redirected (else `null`), and `response` carries the bytes either way.

```bash
const { url, response } = await client.files.content(fileId);
console.log(await response.text());
```

## Delete

`client.files.delete(fileId)` (`DELETE /v1/files/{fileId}`) deletes artifact metadata. Requires `seadb:content:write`.

