# Totalum App Builder API — Source Code & Uploads

This file is the complete reference for this area. The short guide for agents is https://www.totalum.app/totalum-api.md.

- Base URL: `https://builder-api.totalum.app/api/v1/vcaas`
- Authentication: header `api-key: tlm_sk_…` on every request, from a server only.
- Response envelope: `{ "errors": null | { "errorCode", "errorMessage", "errorDetails?" }, "data": … }`.


---

# Source Code & Uploads

> Take your code anywhere; give the agent your files.

The source code is yours: a standard Next.js project you can run locally or host yourself ([For developers](https://www.totalum.app/docs/developers/self-hosting)). Uploaded files are stored in the project's file storage.

## Download Source Code

```endpoint
method: GET
path: /api/v1/vcaas/projects/:projectId/source-code
cost: 2 credits
```

A short-lived link to the project's current code as an archive. With the project's `.env` ([Get Project Env](https://www.totalum.app/docs/api/secrets#get-project-env)) it runs locally with `npm ci && npm run dev`. Downloading source code is included on paid plans.

**Path parameters**

| Parameter | Type | Description |
|---|---|---|
| `projectId` | string | The project id |

**Query parameters**

| Field | Type | Required | Description |
|---|---|---|---|
| `intent` | string | No | `view` when you only show the code (for example in a code viewer), which works on every plan |

**Response fields**

| Field | Type | Description |
|---|---|---|
| `data.filesCount` | number | Files in the archive |
| `data.lastCommitSha` | string \| undefined | Commit of the current version |
| `data.downloadUrl` | string \| null | Signed download URL (valid a few minutes) |

**Example request**

```bash
curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/source-code
```

:::success Success · 200 OK
```json
{ "errors": null, "data": { "filesCount": 96, "lastCommitSha": "9f2c1ab4d3e5f60718293a4b5c6d7e8f90a1b2c3", "downloadUrl": "https://files.totalum.app/source/barber-bookings.tar.gz?sig=…" } }
```
:::

**Error codes**

| Code | HTTP | Meaning |
|---|---|---|
| `PLATFORM_CAPABILITY_QUOTA_REACHED` | 403 | Source download is not included on your plan (`upgradePlan` says which is needed) |
| `INSUFFICIENT_CREDITS` | 402 | Not enough credits |

## Upload File

```endpoint
method: POST
path: /api/v1/vcaas/projects/:projectId/files/upload
cost: Free
```

Upload one file (up to **20 MB**) as `multipart/form-data` with the field `file`. Use the returned `url` in `inputFiles` of [Run AI Agent](https://www.totalum.app/docs/api/agent#run-ai-agent). For a bigger file, pass its own public URL in `inputFiles` instead; no upload is needed.

**Path parameters**

| Parameter | Type | Description |
|---|---|---|
| `projectId` | string | The project id |

**Body parameters** (multipart/form-data)

| Field | Type | Required | Description |
|---|---|---|---|
| `file` | file | Yes | The file, up to 20 MB |
| `private` | string | No | `"true"` = stored privately (served only through signed links) |

**Response fields**

| Field | Type | Description |
|---|---|---|
| `data.fileNameId` | string | The stored file's key |
| `data.url` | string | Its URL (for `inputFiles`) |
| `data.private` | boolean \| undefined | `true` for a private file |

**Example request**

```bash
curl -X POST \
  -H "api-key: tlm_sk_your_key" \
  -F "file=@./logo.png" \
  https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/files/upload
```

:::success Success · 200 OK
```json
{ "errors": null, "data": { "fileNameId": "uploads/01k6y1-logo.png", "url": "https://files.totalum.app/barber-bookings/uploads/01k6y1-logo.png" } }
```
:::

**Error codes**

| Code | HTTP | Meaning |
|---|---|---|
| `MISSING_FILE` | 400 | No multipart field `file` |
| `FILE_TOO_LARGE` | 413 | Over 20 MB — pass the file's own URL in `inputFiles` instead |
| `RATE_LIMITED` | 429 | More than 300 uploads a minute |
