# Create file

`create_file`

| Through | Form |
|---|---|
| HTTP | `POST https://api.markdownbrain.ai/v1/files` |
| MCP | tool `create_file` |
| CLI | `mdbrain call create_file` |

Create a markdown file in a workspace (optionally with initial content). A name that isn't markdown or an image is given a .md extension. Say where with a full `path` (e.g. "ideas/04-my-idea.md" — the folder must already exist), or with `name` plus `parent_path` (a folder path; "" or omitted means the workspace root) or `parent_id`. The response carries the new file's `path`, which is what to address it by — the extension may have been coerced. Creating `brain-config.yaml` at the workspace root, which only the brain keeper may do, creates the brain's configuration, which takes effect at once: the response then also carries `compile`, as [`apply_edits`](/docs/operations/apply_edits) describes. Link other documents as `[title](/path.md)`, rooted at the brain.

**Who may call it:** agents and people.

**Writes:** yes.

## Arguments

| Name | Type | Required | Travels in | Description |
|---|---|---|---|---|
| `workspace_id` | string | yes | JSON body | The workspace to create the file in |
| `path` | string | no | JSON body | Full workspace-relative path including the filename, e.g. "ideas/04-my-idea.md". The folder must already exist. The filename gets a .md extension unless it is already markdown or an image, so read the returned `path` rather than assuming this one. Alternative to name + parentPath/parentId |
| `parent_id` | string or null | no | JSON body | Folder id, or null/omitted for the workspace root |
| `parent_path` | string | no | JSON body | Folder path, e.g. "specs"; "" or omitted means the workspace root |
| `name` | string | no | JSON body | The filename, when the folder is given separately. Omit when passing path |
| `content` | string | no | JSON body | The file's text. Omitted for the root `brain-config.yaml`, the file starts from the commented example a person's palette writes |

## Success

`201` with `application/json`.

## Example request

```sh
curl -X POST https://api.markdownbrain.ai/v1/files \
  -H "Authorization: Bearer $MDBRAIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workspace_id":"00000000-0000-4000-8000-000000000010","path":"research/invitations.md","content":"# Invitation expiry\n\nMost tools expire an invitation after seven days.\n"}'
```

```sh
mdbrain call create_file \
  --workspace-id 00000000-0000-4000-8000-000000000010 \
  --path research/invitations.md \
  --content '# Invitation expiry

Most tools expire an invitation after seven days.
'
```

## Example response

> Written from the code rather than captured from a call.

```json
{
  "file_id": "00000000-0000-4000-8000-000000000109",
  "name": "invitations.md",
  "path": "research/invitations.md"
}
```

## Refusals

A refusal is a status code with `{ error: { code, message } }`. See [Errors](/docs/errors).
