# DriveBot

DriveBot (https://drivebot.in) is a shared, versioned file drive built for AI agents
and the people they work with. It is a Dropbox-style product with an API
designed so that agents such as Claude, Codex, OpenClaw, Instinct and Muse
can open accounts, read documents, search, write files and share links
without a human at a browser.

Key facts:
- Sign-in is by mobile phone number and one-time SMS code; an agent can
  complete it by asking its human for the code and receives its own API key.
- Every write creates a new version with an author (person or agent) and a
  commit-style message; nothing is lost until deliberately purged.
- Organizations with owner/admin/member/billing roles, workspaces with
  admin/editor/viewer roles, teams, phone invites, and an org-wide audit log.
- Agent API keys carry grants per workspace (read or write, folder scope)
  or for a whole org, with optional expiry, IP allowlist and rate limit.
- Text is extracted from PDF, Word, Markdown, code, CSV and JSON files for
  reading and hybrid (keyword + semantic) search.
- Integrations: REST API (OpenAPI at https://drivebot.in/openapi.json) and an MCP
  server at https://drivebot.in/mcp (manifest at https://drivebot.in/.well-known/mcp.json).
- Free to use; 2 GB per file. Support: https://drivebot.in/support.


# DriveBot API guide

DriveBot is file storage for AI agents and the people they work with. This
page is the complete reference. Everything in the web app can also be done
over HTTPS + JSON with `curl`.

Base URL: `https://drivebot.in/api/v1`
Auth header: `Authorization: Bearer <token>` (or `X-API-Key: <token>`)

Two kinds of credential:

| Token | Looks like | Who | Reach |
|---|---|---|---|
| **API key** | `adk_…` | an agent | the workspaces it was granted (see *Agent keys*) |
| **Session** | `ads_…` | a human (or an agent acting fully as one) | everything that person can do |

Prefer API keys for day-to-day work. Use a session only for account and
organization administration.

**Every response explains itself.** Successful calls return
`{"ok": true, "message": "…", …data}` where `message` says in plain words
what happened and what to do next (e.g. that an invite was created and
when it activates). Failures return `{"ok": false, "error": code,
"message": why, "hint": what to do, "docs": url}` with the matching HTTP
status. Read `message` before deciding your next step.

---

## 1. Opening an account (phone + one-time code)

Sign-in is phone based and an agent can drive it. Ask your human for their
mobile number in E.164 form (e.g. `+919876543210`).

```bash
# 1. Send a code by SMS
curl -s -X POST https://drivebot.in/api/v1/auth/otp/send \
  -H 'content-type: application/json' -d '{"phone":"+919876543210"}'
# 2. Ask the human: "What 6-digit code did you just receive?"
# 3. Verify. Optionally mint yourself an API key in the same call.
curl -s -X POST https://drivebot.in/api/v1/auth/otp/verify \
  -H 'content-type: application/json' \
  -d '{"phone":"+919876543210","code":"123456","name":"Priya",
       "agent":{"name":"claude","type":"claude","permission":"write"}}'
```

Response:

```json
{"token":"ads_…","new_user":true,
 "user":{"id":1,"phone":"+919876543210","name":"Priya"},
 "workspace":{"id":1,"name":"My Drive"},
 "api_base":"https://drivebot.in/api/v1/workspaces/1",
 "api_key":"adk_…","agent":{"name":"claude","grants":[…]}}
```

The response also lists every `workspaces` entry the account can reach.
By default the key is minted for the user's first workspace; pass
`"agent": {…, "workspace_id": 7}` (or `"workspace": "Acme specs"`) to
target another, or `"all": true` to get one key that reaches every
workspace in that workspace's organization.

First-time numbers get an account, a **personal organization**, and a
workspace called *My Drive*. Returning numbers get the same account back.
Any pending invites for that number activate automatically. Store
`api_key` durably; it is shown once. Codes expire in 10 minutes, work once,
and lock after 5 wrong tries.

`GET /me` tells you who you are. With a session it lists your `orgs`; with
an API key it lists the `workspaces` the key can reach and the permission
on each. `PATCH /me` `{"name": "Priya S"}` changes the display name
(session only). `POST /auth/logout` ends a session.

---

## 2. Organizations, members, teams and roles

Workspaces live in organizations. Everyone has a personal org; companies
create shared orgs and invite people by phone.

**Org roles** — `owner` (everything, including deleting the org and
managing other owners) · `admin` (members, teams, workspaces, keys, audit;
automatically an admin of every workspace) · `member` (only workspaces
they are granted) · `billing` (settings and audit log only).

**Workspace roles** — `admin` (members, keys, rename) · `editor`
(read/write/share) · `viewer` (read). A person's effective role is the
highest of their direct membership, any team grant, and their org role.

Session token required for all of these (`ORG` = org id):

| Call | Body / notes |
|---|---|
| `GET /orgs` | Your orgs with your role in each; `personal: true` marks the personal one |
| `POST /orgs` | `{"name": "Acme Inc"}` → you become `owner` |
| `GET /orgs/ORG` | Org, your role and your `permissions` list |
| `PATCH /orgs/ORG` | `{"name"}` (needs `org.settings`) |
| `DELETE /orgs/ORG` | owners only; personal orgs cannot be deleted |
| `GET /orgs/ORG/members` | `members` + pending `invites` |
| `POST /orgs/ORG/members` | `{"phone": "+91…", "role": "member"}`. Known number → added now (`status: added`); unknown → invite (`status: invited`) that activates when they first sign in |
| `PATCH /orgs/ORG/members/USER_ID` | `{"role"}`; only owners can create or change owners; the last owner can't be demoted |
| `DELETE /orgs/ORG/members/USER_ID` | removes them from the org and all its workspaces and teams |
| `DELETE /orgs/ORG/invites/ID` | cancel a pending invite |
| `GET /orgs/ORG/teams` · `POST /orgs/ORG/teams` | `{"name", "description"?}` |
| `GET /orgs/ORG/teams/ID` | team + members |
| `PATCH` / `DELETE /orgs/ORG/teams/ID` | rename / delete |
| `POST /orgs/ORG/teams/ID/members` | `{"phone"}` — must already be an org member, or an invite is created |
| `DELETE /orgs/ORG/teams/ID/members/USER_ID` | |
| `GET /orgs/ORG/workspaces` | workspaces you can reach in the org (admins see all) |
| `POST /orgs/ORG/workspaces` | `{"name"}` (needs `org.workspaces`); you become its `admin` |
| `GET /orgs/ORG/audit` | see *Audit log* |

Typical onboarding of a company, as an agent with a session token:

```bash
S="Authorization: Bearer $SESSION"; J='content-type: application/json'
ORG=$(curl -s -X POST https://drivebot.in/api/v1/orgs -H "$S" -H "$J" -d '{"name":"Acme Inc"}' | jq .id)
curl -s -X POST https://drivebot.in/api/v1/orgs/$ORG/members -H "$S" -H "$J" -d '{"phone":"+14155550123","role":"admin"}'
TEAM=$(curl -s -X POST https://drivebot.in/api/v1/orgs/$ORG/teams -H "$S" -H "$J" -d '{"name":"Engineering"}' | jq .id)
curl -s -X POST https://drivebot.in/api/v1/orgs/$ORG/teams/$TEAM/members -H "$S" -H "$J" -d '{"phone":"+14155550123"}'
WS=$(curl -s -X POST https://drivebot.in/api/v1/orgs/$ORG/workspaces -H "$S" -H "$J" -d '{"name":"Product specs"}' | jq .id)
curl -s -X POST https://drivebot.in/api/v1/workspaces/$WS/teams -H "$S" -H "$J" -d '{"team_id":'$TEAM',"role":"editor"}'
```

---

## 3. Agent keys (`adk_…`)

A key belongs to an org and carries **grants**: which workspaces it may
reach, with `read` or `write`, and a `root_path` folder it is confined to.
`"workspace_id": "*"` (or `null`) means every workspace in the org,
including ones created later. Keys can also carry policies.

| Call | Body / notes |
|---|---|
| `GET /orgs/ORG/keys` | all active keys with grants and policies (needs `org.keys`) |
| `POST /orgs/ORG/keys` | see example; returns `key` once |
| `PATCH /orgs/ORG/keys/ID` | any of `name`, `grants` (replaces all), `expires_in_days`, `expires_at`, `ip_allowlist`, `rate_limit_per_min` |
| `DELETE /orgs/ORG/keys/ID` | revoke immediately |
| `GET/POST /workspaces/WS/keys` | shortcut for single-workspace keys (needs `ws.keys`); `{"name","type"?,"permission","root_path"?,"expires_in_days"?}` |
| `DELETE /workspaces/WS/keys/ID` | only if the key reaches nothing else |

```bash
curl -s -X POST https://drivebot.in/api/v1/orgs/$ORG/keys -H "$S" -H "$J" -d '{
  "name": "research-bot", "agent_type": "claude",
  "grants": [
    {"workspace_id": 12, "permission": "write", "root_path": "/reports"},
    {"workspace_id": "*", "permission": "read"}
  ],
  "expires_in_days": 90,
  "ip_allowlist": ["203.0.113.0/24"],
  "rate_limit_per_min": 600
}'
```

Policy failures: `401 key_expired`, `403 ip_not_allowed`, `429
rate_limited` (with `Retry-After`). Every action a key takes is recorded
as `agent:<name>` in file history and the audit log.

---

## 4. Workspaces and files

All file calls live under `/workspaces/WS`. `GET /workspaces` lists the
ones you can reach. `GET /workspaces/WS` shows your effective role,
`permissions` and `root_path`; `PATCH /workspaces/WS` `{"name"}` renames.

**Paths** are absolute and `/`-separated: `/`, `/reports`,
`/reports/q3.md`. No `.` or `..`. Parent folders are created automatically
on write, move and copy.

### Reading

| Call | Purpose |
|---|---|
| `GET /ls?path=/dir[&recursive=true]` | List a folder (recursive = whole subtree) |
| `GET /stat?path=/f` | Metadata: kind, size, version, sha256, updated_by |
| `GET /read?path=/f[&offset=0&limit=200000][&version=N]` | **Extracted text** of text, code, Markdown, JSON, CSV, PDF and DOCX files, paginated by characters. Follow `next_offset` while `truncated` is true |
| `GET /download?path=/f[&version=N]` | Raw bytes (images, binaries). Supports `If-None-Match` with the returned `ETag` |
| `GET /versions?path=/f` | Version history, newest first |
| `GET /search?q=…[&mode=hybrid\|text\|semantic][&path=/dir][&limit=20]` | Search names and contents; best snippet per file |
| `GET /events[?since=EVENT_ID&limit=100]` | Activity in this workspace. Poll with `since` to watch for changes |

### Writing (needs `write`)

| Call | Body |
|---|---|
| `POST /write` | JSON `{"path", "content", "message"?, "if_version"?, "encoding"?: "utf8"\|"base64", "content_type"?}` |
| `PUT /upload?path=/f[&message=..][&if_version=N]` | Raw bytes as the request body (any size/type) |
| `POST /upload` | multipart: `file` + `path`, or `files[]` + `dir` |
| `POST /mkdir` | `{"path"}` |
| `POST /move` | `{"from", "to"}` (also renames) |
| `POST /copy` | `{"from", "to"}` |
| `POST /delete` | `{"path"}` → trash |
| `POST /versions/restore` | `{"path", "version"}` → new version with the old content |

Every write creates a new version and records `message` (like a commit
message). Say what you changed and why. Writing identical content returns
`"status": "unchanged"` and creates no version.

**Avoid clobbering others:** read the file, note its `version`, then write
with `"if_version": <that version>`. If it changed in between you get
`409 conflict`; re-read and merge. `"if_version": 0` creates only if the
file doesn't exist yet.

### Trash

`GET /trash` · `POST /trash/ID/restore` · `DELETE /trash/ID` (purge
forever). Restored items get a ` (2)` suffix if the name is taken.

### Members and teams of a workspace (needs `ws.members`)

| Call | Body |
|---|---|
| `GET /members` | `members`, `teams` (team grants) and, for admins, `org_teams` available to grant |
| `POST /members` | `{"phone", "role": "admin"\|"editor"\|"viewer"}` — unknown numbers get an invite |
| `DELETE /members/USER_ID` | |
| `DELETE /invites/ID` | cancel a pending invite listed by `GET /members` |
| `POST /teams` | `{"team_id", "role"}` grant a whole team |
| `DELETE /teams/TEAM_ID` | |

### Share links (needs `write`)

`POST /shares` `{"path", "permission": "view"|"edit", "expires_in_hours"?}`
returns a public `url` (for people) and `api_url` (for agents, no key
needed). `GET /shares` lists, `DELETE /shares/ID` revokes. Under
`https://drivebot.in/api/v1/s/TOKEN` the calls `/ls`, `/stat`, `/read`, `/download`
work with paths relative to the shared item (plus `/write`, `/upload`,
`/mkdir` for edit shares).

---

## 5. Audit log

`GET /orgs/ORG/audit` (needs `org.audit`; `billing` and above) returns
every administrative action and file event across the org, newest first.
Filters: `actor=agent:codex`, `action=file.` (prefix), `workspace_id=`,
`since=EVENT_ID`, `limit=` (max 5000). Add `format=csv` for a CSV export.

Action names: `file.create/update`, `folder.create`, `node.move/trash/
restore/purge`, `share.create`, `member.add/invite/remove/role`,
`invite.accept/revoke`, `team.create/update/delete`, `team.member.add/
remove`, `team.grant/revoke`, `key.create/update/revoke`,
`workspace.create/rename`, `org.create/update`.

---

## 6. MCP server (for Muse, Claude, Codex and other MCP clients)

DriveBot is also a Model Context Protocol server at `https://drivebot.in/mcp`
(Streamable HTTP transport, JSON responses). Authenticate with the same
bearer token as the REST API: `Authorization: Bearer <DriveBot API key>`.
Tools: `list_workspaces`, `list_files`, `read_file`, `search`,
`write_file`, `create_folder`, `move`, `delete`, `file_versions`,
`create_share_link`, `recent_activity`. Call `list_workspaces` first;
every tool result begins with a plain-language message.

Example client config (Claude Code / Codex style):

```json
{"mcpServers": {"drivebot": {"type": "http", "url": "https://drivebot.in/mcp",
  "headers": {"Authorization": "Bearer adk_…"}}}}
```

## 7. Quick examples

```bash
H="Authorization: Bearer $DRIVEBOT_KEY"
API=https://drivebot.in/api/v1/workspaces/$WS

curl -s "$API/ls?path=/" -H "$H"
curl -s "$API/read?path=/specs/api.md" -H "$H"
curl -s "$API/search?q=refund+policy" -H "$H"
curl -s -X POST "$API/write" -H "$H" -H 'content-type: application/json' \
  -d '{"path":"/notes/summary.md","content":"# Summary\n...","message":"Summarised Q3 docs"}'
curl -s -X PUT "$API/upload?path=/data/report.pdf" -H "$H" --data-binary @report.pdf
curl -s "$API/download?path=/data/report.pdf" -H "$H" -o report.pdf
```

## 8. Getting help

Humans: https://drivebot.in/support (FAQ + contact form) or support@drivebot.in.
Agents can file a support request directly, no key needed:
`POST /support {"name"?, "contact": "email or phone", "subject", "message"}`
→ returns a ticket id. Include what you were trying to do and the exact
error `message` you received.

## 9. Errors

JSON `{"error": code, "message": text}`. Common codes: `400` bad
path/params (`invalid_path`, `invalid_phone`, `no_grants`, `last_owner`…),
`401` bad/expired token or `otp_rejected`, `403 forbidden` (role, read-only
key, outside `root_path`, `ip_not_allowed`), `404 not_found`, `409`
`exists`/`conflict`, `413` too large, `415 not_text` (use `/download`),
`422` validation details, `429 rate_limited`.


# Frequently asked questions

## What is DriveBot?

DriveBot is a shared, versioned file drive built for AI agents and the people they work with. Agents such as Claude, Codex, OpenClaw, Instinct and Muse use it through a REST API or MCP; people use the web app. Every change is versioned and attributed to the person or agent that made it.

## How does an agent get access?

An agent signs in with its human's mobile number: it calls POST /api/v1/auth/otp/send, asks the human for the 6-digit SMS code, then calls POST /api/v1/auth/otp/verify with an agent block and receives its own scoped API key in the same response. No browser is needed.

## I did not receive my sign-in code

Codes arrive by SMS within a minute and expire after 10 minutes. Check that the number includes your country code (e.g. +91), then use Resend code. Five wrong attempts lock the code; request a new one.

## I invited someone but nothing seems to happen

If the number has no DriveBot account yet, an invite is created and shows under Pending invites on the Members page. They get access automatically the first time they sign in at drivebot.in/app with that exact number. If the invite shows a number without a country code, cancel it and add the number again.

## My agent gets 403 forbidden

The response message says why: the key may be read-only, limited to a folder, or lacking a role. Check the key on the workspace's Agents page or the organization's Agent keys page and adjust its grants.

## I lost an API key

Keys are shown once. Revoke the old one and create a new one; the agent's history stays attached to its name.

## How do I connect Muse, Claude or Codex?

Use the MCP endpoint https://drivebot.in/mcp with your API key as a Bearer token, or the REST API described at https://drivebot.in/llms.txt. Every response explains what happened and what to do next.

## What file types can agents read?

Text, Markdown, code, JSON, CSV, PDF and Word (.docx) files are extracted to text for reading and search. Any other file (images, archives, binaries) can be stored and downloaded as raw bytes.

## Can I get my data out?

Yes: download any file or version from the app, or use GET /download and GET /versions via the API. Deleted items stay in the trash until you purge them.

## Is DriveBot free?

DriveBot is free to use today with a 2 GB per-file limit. Organizations, teams, roles, audit logs and agent keys with policies are all included.