---
title: "Save an app file"
method: POST
path: "/api/apps/{app_id}/coding/write"
---

# Save an app file

`POST /api/apps/{app_id}/coding/write`

<Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Saves a file into the app, the same way saving in the builder's code editor does.

Base44 writes the file, applies it to the app, and takes care of what the path implies: a backend function is redeployed, an entity or agent schema is parsed and validated, and a change that affects row-level security records a revertible notice on the app's chat.

Sending an empty `content` deletes the file. That is the builder's own convention for this path, so treat an empty string as a delete rather than as a way to blank a file.

Paths are relative to the app root. Entity and agent schemas, workflows and email templates each have one canonical location, and a legacy shorthand is refused with a 400 naming the canonical form. A path that escapes the app is refused the same way.

Writing a backend function deploys it, so the request takes as long as the deploy and answers 422 carrying the compiler's diagnostics when the code doesn't build. Backend functions also need a Builder plan or higher on the app's workspace. Use [Save several app files](/api-reference/save-several-app-files) to write a batch of frontend files in one call.

The response is the app document as it stands after the change, the same shape [Get app](/api-reference/get-app) returns.

<Note>This endpoint accepts a personal API key. Workspace API keys are not authorized for it and are rejected with a 403.</Note>

<Warning>The response includes fields beyond the ones documented here. Don't rely on undocumented response fields, as they can change at any time. Send only the fields documented here. Other request fields are not supported and their behavior can change.</Warning>

## Path parameters

- `app_id` string, required — ID of the app whose code to change.

## Request body

- object
  - `file_path` string, required — Path of the file, relative to the app root.
  - `content` string, required — Full contents to save. An empty string deletes the file, which is this endpoint's convention rather than a way to blank one.

## Response `200`

The app after the write.

- AppSummary — An app in a workspace, limited to the properties the caller requested.
  - `id` string, nullable — ID of the app.
  - `name` string, nullable — Display name of the app.
  - `slug` string, nullable — URL slug for the app, auto generated from the name and app ID or set to a custom value, or `null` if the app has no slug yet. The published URL is built from it.
  - `user_description` string, nullable — Description of the app, or `null` if none was set. On a newly created app this holds the original prompt text.
  - `created_by` string, nullable — Email of the user who created the app.
  - `created_date` string, date-time, nullable — Time the app was created, as a UTC timestamp in ISO 8601 format.
  - `updated_date` string, date-time, nullable — Time the app document was last written, as a UTC timestamp in ISO 8601 format.
  - `status` AppStatusResponse — The app's current build status.
    - `state` 'ready' | 'processing' | 'error', required — Where the app is in its build lifecycle. Ready means idle with no build in progress, processing means the app is being generated or modified, and error means the last build failed. This tracks building, not publishing.
    - `details` string, nullable — Human readable note about the current state, such as what is being processed or why it failed, or `null` when there is nothing to report.
    - `request_id` string, nullable — ID of the request that last changed the status, or `null` if the status has never changed. Useful when reporting an issue.
    - `last_updated_date` string, date-time, nullable — Time the status was last updated, as a UTC timestamp in ISO 8601 format.
    - `error_source` string, nullable — Where the failure originated when `state` is `error`, or `null` otherwise. A value of `paywall` means the work was blocked because the app's workspace has no credits left.
    - `paywall_context` PaywallStatusContextResponse
      - `billing_organization_id` string, required — ID of the billing organization the paywall was evaluated against.
      - `user_id` string, required — ID of the user the paywall was evaluated for.
      - `evaluated_at` string, date-time, required — Time the paywall condition was evaluated, as a UTC timestamp in ISO 8601 format.
  - `last_deployed_at` string, date-time, nullable — Time the app was last published, as a UTC timestamp in ISO 8601 format, or `null` if it has never been published.
  - `screenshot_url` string, nullable — URL of a screenshot of the published app. Captured shortly after each publish, so it can briefly lag or be `null` right after publishing.
  - `preview_screenshot_url` string, nullable — URL of a preview screenshot taken before publishing, distinct from `screenshot_url`, or `null` if none has been captured.

## Other responses

- `400` — `file_path` escapes the app, or uses a legacy location for an entity or agent schema, a workflow or an email template instead of its canonical one.
- `401` — Missing or invalid credentials.
- `403` — You don't have access to this app, or you used a workspace API key. Writing a backend function also needs a Builder plan or higher on the app's workspace.
- `404` — App not found.
- `409` — The app is on a branch this change can't be made on: a branch that has been merged or closed, a protected main, or a path the branch refuses.
- `422` — A backend function in this write failed to build. The detail carries the compiler diagnostics.

---

[API](https://skmtc.dev/base44/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/base44/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/base44/base44-app-management-api/revisions/173e4e9c63c2/schema)
