Docs
BlogHomeStart building

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). Uploaded files are stored in the project's file storage.

#Download Source Code

GET/api/v1/vcaas/projects/:projectId/source-codeapi-key2 credits

A short-lived link to the project's current code as an archive. With the project's .env (Get Project Env) it runs locally with npm ci && npm run dev. Downloading source code is included on paid plans.

Path parameters

ParameterTypeDescription
projectIdstringThe project id

Query parameters

FieldTypeRequiredDescription
intentstringNoview when you only show the code (for example in a code viewer), which works on every plan

Response fields

FieldTypeDescription
data.filesCountnumberFiles in the archive
data.lastCommitShastring | undefinedCommit of the current version
data.downloadUrlstring | nullSigned download URL (valid a few minutes)

Example request

curl -H "api-key: tlm_sk_your_key" \
  https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/source-code
Success · 200 OK
json
{ "errors": null, "data": { "filesCount": 96, "lastCommitSha": "9f2c1ab4d3e5f60718293a4b5c6d7e8f90a1b2c3", "downloadUrl": "https://files.totalum.app/source/barber-bookings.tar.gz?sig=…" } }

Error codes

CodeHTTPMeaning
PLATFORM_CAPABILITY_QUOTA_REACHED403Source download is not included on your plan (upgradePlan says which is needed)
INSUFFICIENT_CREDITS402Not enough credits
End of Download Source CodeNext endpointPOSTUpload File

#Upload File

POST/api/v1/vcaas/projects/:projectId/files/uploadapi-keyFree

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. For a bigger file, pass its own public URL in inputFiles instead; no upload is needed.

Path parameters

ParameterTypeDescription
projectIdstringThe project id

Body parameters(multipart/form-data)

FieldTypeRequiredDescription
filefileYesThe file, up to 20 MB
privatestringNo"true" = stored privately (served only through signed links)

Response fields

FieldTypeDescription
data.fileNameIdstringThe stored file's key: the key that List Files shows and Delete Files takes
data.urlstringIts URL (for inputFiles); "" for a private file
data.privateboolean | undefinedtrue for a private file
data.createdAtstringWhen it was stored (ISO 8601)

Example request

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 · 200 OK
json
{
  "errors": null,
  "data": {
    "fileNameId": "p/barber-bookings/01JC8Z3K4M5N6P7Q8R9S0T1V2W.png",
    "url": "https://files.totalum-project.com/p/barber-bookings/01JC8Z3K4M5N6P7Q8R9S0T1V2W.png",
    "createdAt": "2026-11-01T10:15:00.000Z"
  }
}

Error codes

CodeHTTPMeaning
MISSING_FILE400No multipart field file
FILE_TOO_LARGE413Over 20 MB — pass the file's own URL in inputFiles instead
RATE_LIMITED429More than 300 uploads a minute

#List Files

GET/api/v1/vcaas/projects/:projectId/filesapi-keyFree

The files stored in the project, newest first: the ones uploaded through Upload File and the ones the app itself stored. Projects on the new engine only; a legacy project answers 400 ENGINE_NOT_SUPPORTED.

Path parameters

ParameterTypeDescription
projectIdstringThe project id

Query parameters

FieldTypeRequiredDescription
folderstringNoOnly the files stored in this folder or its subfolders
typestringNoContent type, e.g. application/pdf, or its first part, e.g. image
namestringNoPart of the file name (not case-sensitive)
createdFromstringNoStored at or after this time (ISO 8601)
createdTostringNoStored at or before this time (ISO 8601)
cursorstringNonextCursor of the previous page
limitnumberNoPage size. Default 100, max 100

Response fields

FieldTypeDescription
data.items[].keystringThe file's key (the fileNameId of its upload)
data.items[].fileNamestringFile name
data.items[].fileSizenumberSize in bytes
data.items[].contentTypestringe.g. image/png
data.items[].visibilitystring"public-by-link" or "private"
data.items[].createdAtstringWhen it was stored (ISO 8601)
data.nextCursorstring | nullPass it as cursor for the next page; null on the last page

Example request

curl -H "api-key: tlm_sk_your_key" \
  "https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/files?type=image&limit=20"
Success · 200 OK
json
{
  "errors": null,
  "data": {
    "items": [
      {
        "key": "p/barber-bookings/01JC8Z3K4M5N6P7Q8R9S0T1V2W.png",
        "fileName": "logo.png",
        "fileSize": 48213,
        "contentType": "image/png",
        "visibility": "public-by-link",
        "createdAt": "2026-11-01T10:15:00.000Z"
      }
    ],
    "nextCursor": null
  }
}

Error codes

CodeHTTPMeaning
VALIDATION_ERROR400A filter is invalid, e.g. limit over 100 or a date that is not ISO 8601
ENGINE_NOT_SUPPORTED400A legacy project
PROJECT_NOT_FOUND404Project does not exist or you don't own it

#Delete Files

DELETE/api/v1/vcaas/projects/:projectId/filesapi-keyFree

Delete stored files by key, for example when a user asks you to erase their documents. Up to 100 keys per call. Free at any balance, and safe to repeat: a key that is already deleted (or never existed) comes back in notFound, not as an error. Projects on the new engine only; a legacy project answers 400 ENGINE_NOT_SUPPORTED.

What happens to a deleted file

  • Its public URL stops being served everywhere within 1 hour: a location of Cloudflare's network that cached the file can keep serving its copy for up to 1 hour after the delete, then the URL answers 410 Gone (404 once the recovery copy is gone). A browser that already downloaded the file can keep its own copy for up to 1 hour after that download.
  • Signed URLs to it stop working at once, including the ones created before the delete.
  • It disappears from List Files and stops counting toward the project's storage.
  • A recovery copy is kept for 30 days, then removed for good (the nightly backup copy too).
  • Deleting the project deletes all of its files.

Path parameters

ParameterTypeDescription
projectIdstringThe project id

Body parameters

FieldTypeRequiredDescription
keysstring[]Yes1 to 100 file keys: the fileNameId of Upload File, the key of List Files

Response fields

FieldTypeDescription
data.deletedstring[]The keys deleted by this call
data.notFoundstring[]The keys with no file to delete (already deleted, or never stored)

Example request

curl -X DELETE \
  -H "api-key: tlm_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"keys": ["p/barber-bookings/01JC8Z3K4M5N6P7Q8R9S0T1V2W.png"]}' \
  https://builder-api.totalum.app/api/v1/vcaas/projects/barber-bookings/files
Success · 200 OK
json
{
  "errors": null,
  "data": {
    "deleted": ["p/barber-bookings/01JC8Z3K4M5N6P7Q8R9S0T1V2W.png"],
    "notFound": []
  }
}
Error · 403
json
{
  "errors": {
    "errorCode": "FILE_KEY_FORBIDDEN",
    "errorMessage": "Not files of project barber-bookings: p/other-project/01JC8Z3K4M5N6P7Q8R9S0T1V2X.pdf",
    "errorDetails": { "keys": ["p/other-project/01JC8Z3K4M5N6P7Q8R9S0T1V2X.pdf"] }
  },
  "data": null
}

Error codes

CodeHTTPMeaning
VALIDATION_ERROR400keys is missing, empty, over 100, or not all strings
ENGINE_NOT_SUPPORTED400A legacy project
FILE_KEY_FORBIDDEN403A key is not one of this project's files (another project's, or malformed). Nothing is deleted
PROJECT_NOT_FOUND404Project does not exist or you don't own it
End of Delete Files Back to top