/-separated path such as Contracts/2026; every source is either in one folder or at the top level (""). The methods on this page list, create, rename, remove and delete folders, and move sources between them. Folders also appear on other methods:
listreturns each source’sfolderand can filter by folder.ingest_file,ingest_url,ingest_github,ingest_youtubetake an optionalfolder.ask,extractandretrieve_chunkstake an optionalfolderslist.
Folders are available on the REST API today. In the SDKs they land in the next releases: Python
graphor 0.28.0, TypeScript graphor 0.25.0 and the MCP package graphor-mcp 0.25.0. The folder methods, parameters and response fields shown for the SDKs need those versions or later; the hosted remote MCP server offers the folder tools once it runs graphor-mcp 0.25.0.Method overview
- Python
- TypeScript
List folders
Returns every folder of the project: folders created empty, folders that hold sources and folders that uploads are on their way to, each with the folders above it, sorted. At most 10,000 are returned;truncated is true when the project has more.
- Python
- TypeScript
Create a folder
Creates a folder, and the folders above it, that stays listed while it is empty. Safe to repeat:created is false when it already existed. You do not need to create a folder before uploading or moving into it.
- Python
- TypeScript
Rename or move a folder
Renames a folder, or moves it under another folder, with its sources and subfolders. Withmerge, a folder that already exists at new_folder is merged instead of refused.
- Python
- TypeScript
Remove a folder
Removes a folder and moves its sources and subfolders into the folder above it (the top level for a top-level folder). Withmerge, a subfolder that lands on a folder of the same name is merged instead of refused.
- Python
- TypeScript
Delete an empty folder
Deletes a folder that holds no source, with the empty folders below it. Move or delete its sources first.- Python
- TypeScript
Move sources
Moves 1 to 1,000 sources to a folder;"" or "/" is the top level. A folder that does not exist is created. Ids that match no source of the project come back in not_found. Safe to repeat.
- Python
- TypeScript
Retries
rename_folder, remove_folder and delete_folder (renameFolder, removeFolder, deleteFolder) never retry on their own, whatever max_retries / maxRetries says on the client or on the call. After a 503, a timeout or a lost connection the change may have been saved, and a repeated call would answer NotFoundError with code folder.not_found. Before repeating one of them yourself, call list_folders and check whether the change is already there.
list_folders, create_folder and move are safe to repeat and follow the client’s retry setting. Folder conflicts (409) are never retried: the API marks them as final.
Error handling
Errors are the SDK’s usual status errors. The API’scode is in the error body: e.body["code"] in Python, err.error.code in TypeScript.
- Python
- TypeScript
When the API does not apply a folder
The SDK never returns a result whose folder filter or scope the API did not apply. It raisesFolderScopeNotAppliedError instead (exported from graphor in both SDKs; a subclass of GraphorError, not an HTTP status error, and never retried). This happens only against an API without folder support, for example an older or separate deployment. Its parameter says what was not applied, and after ask it also carries the conversation id (conversation_id in Python, conversationId in TypeScript). It is raised by:
After
FolderScopeNotAppliedError on ask, the API has already answered the question in its conversation, unscoped. Repeat the question with reset=True (reset: true) or without conversation_id, so the next answer does not build on it.
A direct ingest_file (small files) and ingest_url, ingest_github, ingest_youtube are not checked, because the source is already created when the response arrives; on an API without folder support they land at the top level. Check where they landed with list(folder=...).
The checks run on every parsed result, including Python’s with_raw_response / with_streaming_response .parse() (also .parse(to=dict) or a list of dicts) and TypeScript’s .withResponse(). Reading the raw response skips them: Python .read(), .text(), .json(), http_response, or .parse(to=...) into httpx.Response, str, bytes or bytearray; TypeScript .asResponse() (except on the six folder methods, where a missing route is still raised).
When a scoped ask or extract fails after the API started streaming, the SDK raises the status error the API reports, with retry_after from the body available as the error’s Retry-After header; in Python this holds in strict response-validation mode too.
folders must be a list (Python: a list or a tuple) or an array (TypeScript). Any other value, such as a single string or a set, raises a plain GraphorError before any request is sent.
- Python
- TypeScript
Example: file sources by year
- Python
- TypeScript
Next steps
List sources
List the sources of a folder
Ingest sources
Store new sources in a folder
Chat
Ask questions about the sources of a folder
Folders API reference
Paths, the top level, error codes and limits

