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 binarypath— 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.
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) or1h
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. |