EzyShare API Reference

Self-hosted, multi-tenant file sharing with a developer-first JSON API.

Getting Started

Register a user account to receive an access token and a refresh token. Use the access token as a Bearer credential for all protected endpoints.

Base URL

All endpoints are relative to the server root. Examples below omit the host for brevity.

Authentication

EzyShare uses JWT access and refresh tokens. Tokens are returned as HttpOnly cookies and may also be returned in the response body.

Register

POST /api/auth/register

Request body:

{
    "email": "user@example.com",
    "password": "secure-password",
    "name": "User Name"
}

Returns a new user and tokens.

Login

POST /api/auth/login

Request body:

{
    "email": "user@example.com",
    "password": "secure-password"
}

Refresh Token

POST /api/auth/refresh

Returns a new access token using the refresh token cookie.

Get Current User

GET /api/auth/me

Requires Authorization: Bearer <access-token>.

Logout

POST /api/auth/logout

Clears the refresh token cookie.

Projects

Projects are top-level containers for files and members.

List Projects

GET /api/projects

Returns projects accessible to the current user or API key. Accepts JWT or API key authentication.

Create Project

POST /api/projects

Request body:

{
    "name": "My Project",
    "description": "Optional description"
}

Requires JWT. Project creation may be disabled by an admin.

Get Project

GET /api/projects/{id}

Returns project metadata. Requires project access via JWT or API key.

Update Project

PUT /api/projects/{id}

Request body:

{
    "name": "Updated Name",
    "description": "Updated description",
    "is_public": false
}

Requires JWT. Only the project creator or an admin may update. API keys cannot update projects.

Files

Files are stored inside projects and accessed by path.

List Files

GET /api/projects/{id}/files?path=&recursive=

Lists files in the project root or a subdirectory. Requires files:read scope.

Get File Info

GET /api/projects/{id}/files/*

Returns metadata for a file or directory. Requires files:read scope.

Append /info to explicitly request file info.

Download File

GET /api/projects/{id}/files/*/download

Streams the file content. If the path is a folder, returns a ZIP archive. Supports HTTP Range headers for resumable downloads.

Upload File

POST /api/projects/{id}/files/upload

Multipart upload. Requires files:write scope.

Form fields:

  • file — the file binary
  • path — optional destination path (defaults to uploaded filename)
curl -X POST /api/projects/{id}/files/upload \
  -H "Authorization: Bearer <token>" \
  -F "file=@document.pdf;type=application/pdf" \
  -F "path=reports/2024/document.pdf"

Delete File

DELETE /api/projects/{id}/files/*

Requires files:delete scope.

Create Directory

POST /api/projects/{id}/directories

Request body:

{
    "path": "reports/2024"
}

Requires files:write scope.

Sharing

Share projects and files with other users, toggle public visibility, or generate secret links.

Create Project Share

POST /api/share/projects/{projectId}/shares

Request body:

{
    "scope_type": "specific",
    "target_project_ids": [2, 3]
}

Requires files:share scope. scope_type may be specific or all.

Get Project Shares

GET /api/share/projects/{projectId}/shares

Requires files:read scope.

Revoke Project Share

DELETE /api/share/projects/{projectId}/shares

Request body:

{
    "scope_type": "specific",
    "target_project_ids": [2]
}

Requires files:share scope.

List Incoming Shares

GET /api/share/projects/{projectId}/incoming?path=

Returns files shared with this project from other projects. Requires files:read scope.

Toggle Project Visibility

POST /api/share/projects/{projectId}/visibility

Request body:

{
    "is_public": true
}

Requires files:share scope.

Project Share Link

POST /api/share/projects/{projectId}/link

Generates a revocable secret link. Requires files:share scope.

GET /api/share/projects/{projectId}/link

Returns the existing share link token if set.

DELETE /api/share/projects/{projectId}/link

Revokes the project share link.

File Share

POST /api/share/projects/{projectId}/files/shares/*

Request body:

{
    "scope_type": "specific",
    "target_project_ids": [2, 3]
}

Shares a single file with other projects. Requires files:share scope.

Get File Shares

GET /api/share/projects/{projectId}/files/shares/*

Requires files:read scope.

Revoke File Share

DELETE /api/share/projects/{projectId}/shares/{shareId}

Requires files:share scope.

Download Shared File

GET /api/share/projects/{projectId}/files/download/*?source_project=

Downloads a file from another project that has been shared with this project. Requires files:read scope.

Toggle File Visibility

POST /api/share/projects/{projectId}/files/visibility/*

Request body:

{
    "is_public": true
}

Requires files:share scope.

File Share Link

POST /api/share/projects/{projectId}/files/link/*

Generates a revocable secret link for a single file. Requires files:share scope.

GET /api/share/projects/{projectId}/files/link/*

Returns the existing file share link token if set.

DELETE /api/share/projects/{projectId}/files/link/*

Revokes the file share link.

Secret Share Links (Public)

GET /share/p/{token}

HTML page for viewing a shared project. No authentication required.

GET /api/share/link/project/{token}

JSON metadata and file listing for a shared project.

GET /api/share/link/project/{token}/download/*

Downloads a file from a shared project by secret token.

GET /share/f/{token}

HTML page for viewing a shared file or folder. No authentication required.

GET /api/share/link/file/{token}

JSON metadata for a shared file. If the file is a folder, includes a file listing.

GET /api/share/link/file/{token}/download

Downloads the shared file by secret token.

GET /api/share/link/file/{token}/download/*

Downloads a file inside a shared folder by secret token.

API Keys

API keys allow programmatic access without a user session. They are scoped to a single project.

List API Keys

GET /api/projects/{id}/keys

Requires JWT. The caller must be a project member or an admin.

Generate API Key

POST /api/projects/{id}/keys

Request body:

{
    "name": "CI Key",
    "expires_at": "2025-12-31T23:59:59Z",
    "scopes": ["files:read", "files:write"]
}

Requires JWT. The caller must be a project member or an admin. The secret is shown once in the response as key.

Revoke API Key

DELETE /api/projects/{id}/keys/{keyId}

Requires JWT. The caller must be a project member or an admin. API keys cannot revoke other keys.

Upload Sessions

Resumable chunked uploads for large files.

Create Upload Session

POST /api/projects/{id}/upload-sessions

Request body:

{
    "path": "large-file.bin",
    "size": 1073741824,
    "content_type": "application/octet-stream"
}

Requires files:write scope. Returns a session object.

Upload Chunk

PUT /api/projects/{id}/upload-sessions/{session_id}/chunks/{chunk_index}

Requires files:write scope. Upload raw binary chunk data in the request body.

Complete Upload Session

POST /api/projects/{id}/upload-sessions/{session_id}/complete

Assembles chunks into the final file.

Get Upload Session

GET /api/projects/{id}/upload-sessions/{session_id}

Abort Upload Session

DELETE /api/projects/{id}/upload-sessions/{session_id}

MCP Tools

EzyShare ships an MCP (Model Context Protocol) server exposing file operations to AI assistants. It is available as a standalone stdio binary (ezyshare-mcp) or as POST /mcp on the main HTTP server.

All tools require prior authentication via initialize with a valid project API key.

Available Tools

list_files

List files in a project directory. Optional path and recursive parameters. Requires files:read scope.

file_info

Get metadata for a file. Requires files:read scope.

upload_file

Upload a file via base64 content or HTTP(S) url. For large files, prefer the REST multipart upload endpoint. Requires files:write scope.

download_file

Download a file (returns base64-encoded content). For large files, prefer the REST download endpoint with Range support. Requires files:read scope.

delete_file

Delete a file or directory. Requires files:delete scope.

create_directory

Create a directory in a project. Requires files:write scope.

move_file

Move or rename a file or directory. Requires files:write scope.

list_shared_files

List privately shared files accessible to the current project. Requires files:read scope.

download_shared_file

Download a privately shared file from a source project. Requires files:read scope.

get_auth_bearer

Get a temporary bearer token for the REST API. Use the returned token as Authorization: Bearer <token> on REST endpoints for large file uploads or any other REST operation. Avoids the need to read the API key from a config file.

Optional parameters:

  • project — project ID (defaults to API key's project)
  • expires_in — token lifetime, e.g. 15m (default) or 1h

Admin

All admin endpoints require a JWT with the admin role.

Users

GET /api/admin/users

Lists all users.

POST /api/admin/users

Request body:

{
    "email": "user@example.com",
    "password": "secure-password",
    "name": "User Name",
    "role": "viewer"
}

PUT /api/admin/users/{id}

Request body:

{
    "email": "user@example.com",
    "name": "Updated Name",
    "role": "admin"
}

DELETE /api/admin/users/{id}

Projects

GET /api/admin/projects

Lists all projects across all users.

POST /api/admin/projects

Request body:

{
    "name": "Project",
    "description": "Description",
    "max_storage": 1073741824
}

Settings

GET /api/admin/settings

Returns global settings.

PUT /api/admin/settings

Updates global settings.

Upload Policies

POST /api/admin/projects/{id}/policies

Request body:

{
    "project_id": null,
    "max_size": 104857600,
    "allowed_mime_types": "image/*,application/pdf",
    "blocked_extensions": ".exe,.bat"
}

Set project_id to null for a global policy, or to a project ID for a project-specific policy.

GET /api/admin/projects/{id}/policies

Not yet implemented.

Rate Limits

POST /api/admin/projects/{id}/rate-limits

Request body:

{
    "project_id": null,
    "route_pattern": "/api/projects/*/files/upload",
    "max_requests": 10,
    "window_seconds": 60
}

Set project_id to null for a global limit.

GET /api/admin/projects/{id}/rate-limits

Returns rate limits for the project.

Max Storage

PUT /api/admin/projects/{id}/max-storage

Request body:

{
    "max_storage": 1073741824
}

Set max_storage to -1 or 0 for unlimited.

Audit Logs

GET /api/admin/audit-logs?limit=

Returns global audit logs.

GET /api/admin/projects/{id}/audit-logs?limit=

Returns audit logs for a specific project.

Public Access

These endpoints are available without authentication.

List Public Projects

GET /public/

Returns a placeholder message. Public project listing is not yet implemented.

Download Public Project File

GET /public/{projectId}/*

Downloads a public file from a project. The file must have public visibility enabled.

Error Codes

Status Meaning
400 Bad request — invalid JSON, missing fields, or invalid parameters.
401 Unauthorized — missing, invalid, or expired token.
403 Forbidden — insufficient permissions, scope, or project membership.
404 Not found — project, file, share, or resource does not exist.
409 Conflict — duplicate share or path already exists.
413 Payload too large — exceeds project or global upload limit.
429 Too many requests — rate limit exceeded.
500 Internal server error.