endorr
Get started

Developers and AI agents

The Endorr Cloud API

Put Endorr Cloud inside your own apps, shops, scripts and AI agents. One API key, plain HTTP, and paths you already know: upload a file in one request.

Everything is JSON over HTTPS at https://auth.endorr.com/v1/cloud. There is no SDK to install, no OAuth dance, and no separate upload host to learn. AI agents can use the same key through the MCP server or the OpenAPI document.

Quickstart

  1. In Endorr Studio, open Settings, API keys and create a key. Give it Read files and Add and change files.
  2. Copy the key. It starts with endorr_sk_ and is shown once.
  3. Upload your first file:
export ENDORR_KEY=endorr_sk_...

curl -T invoice.pdf \
  -H "Authorization: Bearer $ENDORR_KEY" \
  "https://auth.endorr.com/v1/cloud/files?path=/Invoices/2026/invoice.pdf"

That is the whole flow. The Invoices and 2026 folders are created for you, and the answer tells you the file's id and where it landed:

{
  "file": {
    "type": "file",
    "id": "file_01JB8Q...",
    "name": "invoice.pdf",
    "path": "/Invoices/2026/invoice.pdf",
    "folder_id": "fld_01JB8Q...",
    "size_bytes": 48213,
    "content_type": "application/pdf",
    "sha256": "9f2c...",
    "status": "ready",
    "created_via": "api",
    "created_at": "2026-10-21T09:30:00.000Z",
    "updated_at": "2026-10-21T09:30:00.000Z"
  },
  "replaced": false
}

AI agents and MCP

The API is built to be used by agents as much as by people. Point an agent at any of these and it can work out the rest:

WhatWhere
MCP server (Streamable HTTP)https://auth.endorr.com/v1/cloud/mcp
OpenAPI 3.1 documenthttps://auth.endorr.com/v1/cloud/openapi.json
These docs as one Markdown filehttps://endorr.com/developers.md
Index for LLMshttps://endorr.com/llms.txt and https://endorr.com/llms-full.txt
Discovery (no key needed)GET https://auth.endorr.com/v1/cloud

Connect an agent over MCP. Create a key with only the permissions the agent needs, ideally limited to one folder, and add the server with the key as a bearer token. In Claude Code:

claude mcp add --transport http endorr-cloud https://auth.endorr.com/v1/cloud/mcp \
  --header "Authorization: Bearer endorr_sk_..."

Clients configured with JSON (Claude Desktop, Cursor, VS Code and others) take an entry like this:

{
  "mcpServers": {
    "endorr-cloud": {
      "type": "http",
      "url": "https://auth.endorr.com/v1/cloud/mcp",
      "headers": { "Authorization": "Bearer endorr_sk_..." }
    }
  }
}

The agent sees only the tools its key allows:

ToolDoesNeeds
whoamiWho the key acts for, its permissions and folder, storagefiles.read
list_folderList a folder by path or idfiles.read
searchFind files and folders by namefiles.read
get_file_infoA file's detailsfiles.read
read_fileText and images inline (up to 1 MB), else a download linkfiles.read
get_download_linkA short-lived link to the bytesfiles.read
write_fileCreate or overwrite a file from text or base64files.write
create_folderCreate a folder and missing parentsfiles.write
move_or_renameRename or move a file or folderfiles.write
move_to_trashTrash a file or folder (restorable for 28 days)files.delete
create_share_linkA public view-only linkshares.create

Teach a coding agent the API. Paste this into your project's AGENTS.md or CLAUDE.md:

## Endorr Cloud
Files live in Endorr Cloud. API docs: https://endorr.com/developers.md
- Base URL: https://auth.endorr.com/v1/cloud
- Auth: `Authorization: Bearer $ENDORR_KEY` (never commit the key)
- Upload: `PUT /v1/cloud/files?path=/folder/name.ext` with the file as the body
- List: `GET /v1/cloud/folders?path=/folder`; download: `GET /v1/cloud/files/download?path=…` (follow the redirect)
- Errors are `{ "error": { "code", "message", "docs_url" } }`; branch on `code`
Give agents the least they need.A key limited to one folder with only files.read cannot see or change anything else. Agents may not trash files or create public links unless you give the key files.delete or shares.create.

API keys

Send your key on every request as Authorization: Bearer endorr_sk_…. Check a key with GET /v1/cloud/me: it answers who the key acts for, what it may do and how much storage is used.

A key acts as you, inside the workspace you made it in. It can never do more than you can, and only what you allowed when you made it:

PermissionAllows
files.readList, search and download files and folders
files.writeUpload files, create folders, rename and move
files.deleteMove files and folders to the trash (restorable for 28 days)
shares.createCreate view-only share links

Limit a key to one folder and it sees that folder as /, and nothing outside it. That is the safest choice for an app or agent that only needs a place of its own. You can change a key's permissions later without changing the key, set an expiry date, and revoke it at any time; it stops working at once.

Keep keys on your server.A key is like a password. Never put it in a web page, mobile app or public repository. If a key leaks, revoke it in Studio and make a new one.

Paths and ids

Use whichever is easier. Every file and folder can be reached by its path, like /Clients/Acme/logo.png, or by its id, like file_01JB8Q… or fld_01JB8Q…. Ids never change when you rename or move something, so store ids if you keep references.

Paths start at /, are case-sensitive, and never contain . or ... Encode them in a query string as usual (?path=/My%20files/a.pdf). The folder id root also means /.

Upload a file

PUT /v1/cloud/files?path=… with the file as the request body, up to 100 MB. POST works too. The content type comes from the file extension, or from your Content-Type header for extensions we do not know.

When a file with the same name is already there, on_conflict decides:

  • rename (default): keep both. The new one becomes invoice (2).pdf. Nothing is ever lost.
  • overwrite: replace the old file's contents. It keeps its id and share links. The answer has "replaced": true.
  • fail: answer 409 already_exists with the existing file's id in details.file_id.
curl -T report.pdf -H "Authorization: Bearer $ENDORR_KEY" \
  "https://auth.endorr.com/v1/cloud/files?path=/Reports/weekly.pdf&on_conflict=overwrite"

Download a file

GET /v1/cloud/files/{id}/download, or by path with GET /v1/cloud/files/download?path=…. The answer is a redirect to a short-lived link to the bytes, so tell your client to follow redirects. Add redirect=false to get { "url", "expires_at" } instead.

curl -L -o invoice.pdf -H "Authorization: Bearer $ENDORR_KEY" \
  "https://auth.endorr.com/v1/cloud/files/download?path=/Invoices/2026/invoice.pdf"

File details without the bytes: GET /v1/cloud/files/{id} or GET /v1/cloud/files?path=….

List a folder

GET /v1/cloud/folders?path=/Invoices or GET /v1/cloud/folders/{id}. One list of items, folders first, then files, by name. Each item has a type of folder or file.

curl -H "Authorization: Bearer $ENDORR_KEY" "https://auth.endorr.com/v1/cloud/folders?path=/Invoices"

Up to 100 items per page (limit up to 500). When next_cursor is not null, pass it as cursor for the next page.

Create folders

POST /v1/cloud/folders with { "path": "/Clients/Acme/2026" } makes every missing folder on the way. Calling it again is safe: it answers 200 with the existing folder and "created": false instead of an error.

Rename, move, delete

PATCH /v1/cloud/files/{id} or PATCH /v1/cloud/folders/{id} with a new name, a move_to path, or both. The destination folder is created when missing.

curl -X PATCH -H "Authorization: Bearer $ENDORR_KEY" -H "Content-Type: application/json" \
  -d '{"name": "invoice-paid.pdf", "move_to": "/Invoices/Paid"}' \
  "https://auth.endorr.com/v1/cloud/files/file_01JB8Q..."

DELETE /v1/cloud/files/{id} and DELETE /v1/cloud/folders/{id} move things to the trash. You can restore them in Endorr Studio for 28 days.

Share links

POST /v1/cloud/files/{id}/share (or /folders/{id}/share) makes a view-only link anyone can open, for 7 days unless you pass expires_in_days (1 to 365). Add max_downloads to cap downloads.

curl -X POST -H "Authorization: Bearer $ENDORR_KEY" -H "Content-Type: application/json" \
  -d '{"expires_in_days": 30}' "https://auth.endorr.com/v1/cloud/files/file_01JB8Q.../share"

# { "share": { "id": "shr_…", "url": "https://…/s/…", "expires_at": "…" } }

GET /v1/cloud/search?q=invoice finds files and folders whose name contains the text, newest first, with their paths.

Large files

For files over 100 MB (up to 50 GB), upload in three steps so the bytes go straight to storage:

  1. POST /v1/cloud/uploads with { "path", "size_bytes", "content_type" }.
  2. PUT the bytes to upload.url with the headers in upload.headers. No API key on this request.
  3. POST the complete_url from step 1. The file then appears in its folder.
START=$(curl -s -X POST -H "Authorization: Bearer $ENDORR_KEY" -H "Content-Type: application/json" \
  -d "{\"path\": \"/Videos/launch.mp4\", \"size_bytes\": $(stat -f%z launch.mp4)}" "https://auth.endorr.com/v1/cloud/uploads")

curl -T launch.mp4 "$(echo "$START" | jq -r .upload.url)"

curl -X POST -H "Authorization: Bearer $ENDORR_KEY" "https://auth.endorr.com$(echo "$START" | jq -r .complete_url)"

Large uploads support on_conflict=rename and fail. To replace a large file, delete the old one first.

Errors

Every error has the same shape, with a stable code to branch on, a message written for people, and a docs_url pointing here:

{
  "error": {
    "code": "forbidden",
    "message": "This API key lacks the \"files.write\" permission. Add it in Endorr Studio under Settings, API keys.",
    "request_id": "6f1c…",
    "docs_url": "https://endorr.com/developers#errors"
  }
}
StatuscodeWhat to do
401unauthorizedThe key is missing, wrong, expired or revoked.
402storage_quota_exceededThe workspace is out of storage. details says how much is used and free.
403forbiddenThe key lacks a permission, or you cannot edit that folder.
404not_foundNothing at that path or id that this key can see.
409already_existsA file with that name is there and you passed on_conflict=fail.
413payload_too_largeOver 100 MB: use a large upload.
422validation_failedA parameter is missing or wrong; details says which.
429rate_limitedToo many requests. Wait a few seconds and retry.

Mention the request_id when you contact support.

Limits

  • 600 requests per minute per key (an MCP call counts as one).
  • 100 MB per one-request upload; 50 GB per large upload.
  • 25 active keys per person.
  • Storage counts against your plan, the same as files you add in Studio.
  • End-to-end encrypted vault folders from the desktop app cannot be read or written through the API.

Endpoint reference

All paths are relative to https://auth.endorr.com. The same list, with request and response schemas, is in the OpenAPI document.

EndpointDoesNeeds
GET /v1/cloudDiscovery: docs, OpenAPI and MCP linksnothing
GET /v1/cloud/openapi.jsonOpenAPI 3.1 documentnothing
POST /v1/cloud/mcpMCP server for AI agentsper tool
GET /v1/cloud/meWho the key acts for, its permissions, storagefiles.read
GET /v1/cloud/folders?path=List a folder by pathfiles.read
GET /v1/cloud/folders/{id}List a folder by id (root = /)files.read
POST /v1/cloud/foldersCreate a folder and missing parentsfiles.write
PATCH /v1/cloud/folders/{id}Rename or move a folderfiles.write
DELETE /v1/cloud/folders/{id}Move a folder to the trashfiles.delete
POST /v1/cloud/folders/{id}/shareShare link to a foldershares.create
PUT /v1/cloud/files?path=Upload in one requestfiles.write
GET /v1/cloud/files?path=File details by pathfiles.read
GET /v1/cloud/files/{id}File details by idfiles.read
GET /v1/cloud/files/download?path=Download by path (302)files.read
GET /v1/cloud/files/{id}/downloadDownload by id (302)files.read
PATCH /v1/cloud/files/{id}Rename or move a filefiles.write
DELETE /v1/cloud/files/{id}Move a file to the trashfiles.delete
POST /v1/cloud/files/{id}/shareShare link to a fileshares.create
POST /v1/cloud/uploadsStart a large uploadfiles.write
POST /v1/cloud/uploads/{id}/completeFinish a large uploadfiles.write
GET /v1/cloud/search?q=Search by namefiles.read

Questions or something missing? Ask us through the Help center.

Language