API Documentation
Agentic-first file storage for AI agents and developers
Base URL: https://www.easybits.cloud/api/v2
Quick Start
- Create an account at easybits.cloud
- Go to Developer Dashboard and create an API key
- Make your first request:
Get your API key. By default 12 core tools load. Add --tools docs,slides,all for more. See tool groups.
Authentication
All API requests require a Bearer token in the Authorization header.
Claude Cowork (OAuth)
For Claude.ai, Cowork, and other web-based MCP clients that can't store API keys.
EasyBits implements OAuth 2.1 with Dynamic Client Registration (RFC 7591) and PKCE S256. Web MCP clients discover, register, and authenticate automatically — no API key copying, no JSON configs.
Connect in 4 steps
- In Cowork, open Settings → Connectors → Add custom connector
- Paste the MCP URL:
https://www.easybits.cloud/api/mcp - Click Connect — you'll be redirected to EasyBits to log in
- Authorize the connector. You're done — the agent has access to your workspace
?tools=all to the URL to expose all 100+ tools instead of the 12-tool core group. See Tool Groups for other options.How it works
EasyBits exposes the standard OAuth discovery endpoints so any spec-compliant MCP client connects without manual setup:
| Endpoint | Spec | Purpose |
|---|---|---|
| /.well-known/oauth-protected-resource | RFC 9728 | Tells clients which Authorization Server protects /api/mcp |
| /.well-known/oauth-authorization-server | RFC 8414 | Advertises authorize, token, and registration endpoints |
| /oauth/register | RFC 7591 | Dynamic Client Registration — client_id + secret issued on POST |
| /oauth/authorize | OAuth 2.1 | User consent + code issuance (PKCE S256 required) |
| /oauth/token | OAuth 2.1 | Exchanges code + verifier for a 1-hour JWT access token |
Handshake flow
Notes
- Access tokens are HS256 JWTs, valid for 1 hour. No refresh token — reauthorize is a single click when you already have a session.
- Auto-approval: once logged in, the authorize screen redirects back immediately. The user already expressed consent by initiating the flow from the connector.
- Additive: API key Bearer auth keeps working unchanged. The handler tries JWT verification first and silently falls through to API key validation.
- PKCE S256 is mandatory. Plain and no-PKCE flows are rejected.
- Scope: a single
mcpscope — the authorized session has full access to the MCP handler.
SDK
The typed SDK wraps the entire REST API. Install and use it in any Node.js/Bun/Deno project.
All Methods
Files
| Method | Description |
|---|---|
| listFiles(params?) | List files (paginated) |
| getFile(fileId) | Get file + download URL |
| uploadFile(params) | Create file + get upload URL |
| updateFile(fileId, params) | Update name, access, metadata, status |
| deleteFile(fileId) | Soft-delete (7-day retention) |
| restoreFile(fileId) | Restore from trash |
| listDeletedFiles(params?) | List trash with days until purge |
| searchFiles(query) | AI-powered natural language search |
| duplicateFile(fileId, name?) | Copy file (new storage object) |
| listPermissions(fileId) | List sharing permissions |
Bulk Operations
| Method | Description |
|---|---|
| bulkUploadFiles(items) | Upload up to 20 files at once |
| bulkDeleteFiles(fileIds) | Delete up to 100 files at once |
Images
| Method | Description |
|---|---|
| optimizeImage(params) | Convert to WebP/AVIF |
| transformImage(params) | Resize, rotate, flip, convert, grayscale |
Sharing
| Method | Description |
|---|---|
| shareFile(params) | Share with another user by email |
| generateShareToken(fileId, expiresIn?) | Temporary download URL |
| listShareTokens(params?) | List tokens (paginated) |
Webhooks
| Method | Description |
|---|---|
| listWebhooks() | List configured webhooks |
| createWebhook(params) | Create webhook (returns secret once) |
| getWebhook(webhookId) | Get webhook details |
| updateWebhook(webhookId, params) | Update URL, events, or status |
| deleteWebhook(webhookId) | Delete permanently |
Websites
| Method | Description |
|---|---|
| listWebsites() | List static websites |
| createWebsite(name) | Create website, get id + URL |
| getWebsite(websiteId) | Get website details |
| updateWebsite(websiteId, params) | Update name/status |
| deleteWebsite(websiteId) | Delete website + files |
Deploy files by uploading with fileName: "sites/{websiteId}/path" — see Websites section for full example.
Account
| Method | Description |
|---|---|
| getUsageStats() | Storage, file counts, plan info |
| listProviders() | Storage providers |
| listKeys() | API keys |
Error Handling
eb.compute — Managed LLM
Code running inside an EasyBits sandbox can call an LLM without bringing its own API key. EasyBits proxies to the provider, meters the real tokens, and charges your credits in MXN. It speaks the OpenAI Chat Completions wire format, so any framework (the official openai SDK, Vercel AI SDK, LangChain) works by just pointing its base URL.
Base URL: https://compute.easybits.cloud/v1
Inside an agent sandbox this is injected for you as OPENAI_BASE_URL + OPENAI_API_KEY — zero config. The key is scoped to that sandbox and revoked when it's destroyed.
Models
Pass a friendly name in model:
gemini-flash— fast & cheap (default)gemini-pro— higher qualitygpt-4o-miniclaude-sonnet
Quick start (inside a sandbox)
Supported: streaming, tool / function calling, and vision (image input) on all models above.
Billing: per token. Each call records an AiGenerationLog entry and deducts credits; the credits charged are returned in usage.cost. If you're out of credits the request returns 402.
Files
/filesList your files (paginated)
| assetId | string | Filter by asset ID |
| limit | number | Max results (default 50, max 100) |
| cursor | string | Pagination cursor |
| status | string | Set to 'DELETED' to list deleted files |
/files/:fileIdGet file details with a temporary download URL
/filesCreate a file record and get a presigned upload URL
| fileName | string | Required |
| contentType | string | MIME type (required) |
| size | number | File size in bytes (required, 1B–5GB) |
| access | string | 'public' or 'private' (default) |
| region | string | 'LATAM', 'US', or 'EU' |
Upload bytes via PUT to putUrl, then PATCH the file status to 'DONE'.
/files/:fileIdUpdate file name, access level, metadata, or status
| name | string | New file name |
| access | string | 'public' or 'private' |
| metadata | object | Key-value pairs (merged, max 10KB) |
| status | string | Only 'DONE' (from PENDING) |
/files/:fileIdSoft-delete a file (7-day retention)
/files/:fileId/restoreRestore a soft-deleted file
/files/search?q=...AI-powered natural language file search (requires AI key)
| q | string | Natural language query (required) |
/files/:fileId/duplicateCreate a copy of an existing file (new storage object)
| name | string | Name for the copy (optional, defaults to 'Copy of ...') |
/files/:fileId/permissionsList sharing permissions for a file
Bulk Operations
/files/bulk-uploadCreate multiple file records and get presigned upload URLs (max 20)
| items | array | Array of { fileName, contentType, size, access? } |
Each file must be uploaded via PUT to its putUrl, then status set to DONE.
/files/bulk-deleteSoft-delete multiple files at once (max 100)
| fileIds | string[] | Array of file IDs to delete |
Images
/files/:fileId/optimizeConvert image to WebP or AVIF (creates a new file)
| format | string | 'webp' (default) or 'avif' |
| quality | number | 1–100 (default: 80 webp, 50 avif) |
/files/:fileId/transformResize, crop, rotate, flip, or convert an image (creates a new file)
| width | number | Target width in px |
| height | number | Target height in px |
| fit | string | 'cover', 'contain', 'fill', 'inside', 'outside' |
| format | string | 'webp', 'avif', 'png', 'jpeg' |
| quality | number | 1–100 |
| rotate | number | Degrees |
| flip | boolean | Vertical flip |
| grayscale | boolean | Convert to grayscale |
Webhooks
Receive real-time POST notifications when events occur. Payloads are signed with HMAC SHA-256 via the X-Easybits-Signature header. Webhooks auto-pause after 5 consecutive delivery failures.
file.created, file.updated, file.deleted, file.restored, website.created, website.deleted/webhooksList your configured webhooks
/webhooksCreate a webhook. The secret is only returned on creation — save it.
| url | string | HTTPS URL to receive POST notifications (required) |
| events | string[] | Events to subscribe to (required) |
Max 10 webhooks per account. URL must use HTTPS.
/webhooks/:webhookIdGet webhook details (excluding secret)
/webhooks/:webhookIdUpdate webhook URL, events, or status
| url | string | New HTTPS URL |
| events | string[] | New events list |
| status | string | 'ACTIVE' or 'PAUSED'. Reactivating resets fail counter. |
/webhooks/:webhookIdPermanently delete a webhook
Verifying Signatures
Payload Format
Websites
- Create a website — you get an
idand a URL likehttps://my-site.easybits.cloud - Upload files with
fileNameset tosites/{websiteId}/path(e.g.sites/{id}/index.html) - PUT the bytes to each
putUrl, then set status to DONE - Your site is live — SPA fallback to
index.htmlis built-in
Deploy Example
Endpoints
/websitesList your static websites
/websitesCreate a new website
| name | string | Website name (required) |
/websites/:websiteIdGet website details
/websites/:websiteIdUpdate website name or status
| name | string | New name |
| status | string | e.g. 'DEPLOYED' |
/websites/:websiteIdDelete website and soft-delete all its files
Presentations
- Create a presentation with a title, theme, and slides
- Each slide contains HTML content rendered by reveal.js
- Deploy to get a live URL at
slug.easybits.cloud - Update slides and redeploy at any time
Slide Object
Available Themes
black · white · league · beige · night · serif · simple · solarized · moon · dracula · sky
Endpoints
/presentationsList your presentations
/presentations/:presentationIdGet presentation details including slides
/presentationsCreate a new presentation
| title | string | Presentation title (required) |
| theme | string | Reveal.js theme (default: 'black') |
| slides | Slide[] | Array of slide objects with content HTML |
/presentations/:presentationIdUpdate title, theme, or slides
| title | string | New title |
| theme | string | New theme |
| slides | Slide[] | Replace all slides |
/presentations/:presentationIdDelete a presentation and its deployed site
/presentations/:presentationId/deployDeploy presentation as a static site at slug.easybits.cloud
/presentations/:presentationId/unpublishRemove the deployed site
Documents
AI-generated professional documents (reports, brochures, catalogs, proposals, CVs) with parallel page generation, design directions, and semantic color themes.
/documentsList all your documents
/documents/:idGet a document with full page/section data
/documentsCreate a new document
| name | string | Document name (required) |
| prompt | string | Description for AI generation |
| theme | string | Theme: minimal, calido, oceano, noche, bosque, rosa |
| customColors | object | Custom palette: { primary, secondary, accent, surface } |
/documents/:idUpdate document metadata (name, theme, colors). Use page tools for content changes.
| name | string | New name |
| prompt | string | Updated prompt |
| theme | string | Theme name |
| customColors | object | Custom color palette |
/documents/:idDelete a document
/documents/:id/deployPublish as a live website at slug.easybits.cloud
/documents/:id/unpublishRemove the live website and revert to draft
Page Management (MCP)
These tools are available via MCP for surgical page-level editing.
get_page_htmlMCPdocumentId, pageId
Get the HTML and metadata of a single page.
set_page_htmlMCPdocumentId, pageId, html
Update a single page's full HTML. Preferred over update_document for content edits.
get_section_htmlMCPdocumentId, pageId, cssSelector
Get the outerHTML of a specific element within a page by CSS selector.
set_section_htmlMCPdocumentId, pageId, cssSelector, html
Replace a specific element within a page. Enables surgical edits.
add_pageMCPdocumentId, html?, afterPageIndex?, label?
Add a new page. Optionally provide HTML and insertion position.
delete_pageMCPdocumentId, pageId
Remove a page. Cannot delete the last remaining page.
reorder_pagesMCPdocumentId, pageIds
Reorder all pages. pageIds must contain every page ID exactly once.
get_page_screenshotMCPdocumentId, pageIndex?
Take a screenshot of a page. Returns a PNG image (letter-sized). Prefer this tool to verify edits visually.
AI Generation (MCP)
generate_documentMCPdocumentId, prompt, skipCover?
Generate all pages with AI via streaming. Use skipCover: true to add pages without regenerating the cover.
refine_document_sectionMCPdocumentId, sectionId, instruction
Surgical AI changes to a specific page. Use get_page_html to see the result.
regenerate_document_pageMCPdocumentId, sectionId
Completely redesign a page while keeping the same content intent.
enhance_document_promptMCPname, prompt?, action?
Auto-generate a description from the title or improve an existing prompt.
get_document_directionsMCPprompt, pageCount?, sourceContent?
Get 4 design directions (fonts, colors, mood). Pass one to generate_document.
clone_documentMCPdocumentId, name?
Duplicate a document with all its pages.
Workflow
1. enhance_document_prompt — auto-generate a description
2. get_document_directions — get 4 design directions
3. create_document — create the document
4. generate_document — AI generates all pages
5. get_page_screenshot — verify pages visually
6. refine_document_section — tweak individual pages
7. deploy_document — publish at slug.easybits.cloud
Account & Usage
/usageGet account usage statistics: storage, file counts, plan info
/providersList your configured storage providers
/keysList your API keys (session auth only)
Errors & Rate Limits
| Status | Meaning |
|---|---|
| 400 | Bad request (invalid params) |
| 401 | Unauthorized (missing/invalid API key) |
| 403 | Forbidden (insufficient scope) |
| 404 | Resource not found |
| 429 | Rate limited (too many requests) |
| 500 | Server error |
All error responses include a JSON body: {"error": "message"}
Rate limits: 100 requests per 15 minutes for all plans.
Tool Groups
By default the MCP server loads 12 core tools to minimize token usage. Enable additional groups to unlock more capabilities.
| Group | Tools | Description |
|---|---|---|
| core | 12 | Files, DB, documents, quotations, usage stats (default) |
| files | ~37 | All file ops: bulk, sharing, permissions, webhooks, image transforms, AI keys |
| docs | ~33 | All document tools: AI generation, refine, screenshots, structured docs |
| sites | ~8 | Websites: CRUD, file upload, deploy |
| brand | ~8 | Brand kits, templates, themes |
| all | ~104 | Everything |
Usage
MCP Apps UI
EasyBits registers 3 inline UIs using the @modelcontextprotocol/ext-apps spec. These are visual interfaces that MCP clients can render alongside tool results.
File Preview
ExperimentalRenders a rich preview card for any file: images, video, audio, PDF with inline player/viewer, or icon + metadata fallback.
get_fileURI: easybits://apps/file-previewFile Browser
ExperimentalInteractive file list with icons, metadata, access badges. Click a file to trigger get_file and see its preview.
list_filesURI: easybits://apps/file-listFile Upload
ExperimentalDrag & drop dropzone with real-time progress bar. Handles the full upload flow: get presigned URL, PUT bytes, show success.
upload_fileURI: easybits://apps/file-uploadHow It Works
Each app is an HTML document that uses PostMessageTransport to communicate with the MCP client. When a tool is called, the client can render the app's UI inline and pass tool results to it.