Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

API examples

Every request below carries the three headers from Authentication. To keep the examples short, they are in a shell array:

DRIVE=https://tj7hnhcvwir4n6rl5itdqut3mq0wdpke.lambda-url.us-east-1.on.aws
AUTH=(-H "Authorization: Bearer $MACHINE_TOKEN"
      -H "x-granite-grant: $GRANT_ID"
      -H "x-drive-user-context: $USER_CONTEXT")

The responses were captured from Drive’s own code under a grant with drive.read and drive.write over the folder 6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f.

Create a file

POST /v1/files

curl "$DRIVE/v1/files" "${AUTH[@]}" -H "Content-Type: application/json" \
  -d '{
    "name": "shopping.md",
    "content": "Apples\n",
    "mime_type": "text/markdown",
    "directory_id": "6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f"
  }'
FieldRequiredRules
nameYesUp to 255 characters. Unique within its folder.
directory_idYes, under a folder grantA folder the grant covers.
contentNoA string, up to 300,000 bytes.
mime_typeNoThe file’s type.
tagsNoUp to 50 strings of up to 80 characters.

201 Created:

{
  "content": "Apples\n",
  "content_hash": "sha256:d14cbe5383b698ced713c1325292e005a85a051cb10d969893d60fde2ec32c53",
  "created_at": "2026-11-05T20:40:14.87202439Z",
  "directory_id": "6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f",
  "id": "9327802d-b5d8-42e7-a6d5-61d31ffaf600",
  "mime_type": "text/markdown",
  "name": "shopping.md",
  "owner_uid": "usr_7Hq2mV9cXk4tR1pB",
  "size_bytes": 7,
  "tags": [],
  "updated_at": "2026-11-05T20:40:14.87202439Z",
  "version": 1
}

owner_uid is the person’s Drive id. It is the same for every app the person uses.

List files

GET /v1/files lists the files your grant covers that are not in the trash. Filter with ?directory_id=<folder id> or ?tag=<tag>. Entries carry no content; read a file by id for that.

curl "$DRIVE/v1/files?directory_id=6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f" "${AUTH[@]}"
[
  {
    "content_hash": "sha256:d14cbe5383b698ced713c1325292e005a85a051cb10d969893d60fde2ec32c53",
    "created_at": "2026-11-05T20:40:14.87202439Z",
    "directory_id": "6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f",
    "id": "9327802d-b5d8-42e7-a6d5-61d31ffaf600",
    "mime_type": "text/markdown",
    "name": "shopping.md",
    "owner_uid": "usr_7Hq2mV9cXk4tR1pB",
    "size_bytes": 7,
    "tags": [],
    "updated_at": "2026-11-05T20:40:14.87202439Z",
    "version": 1
  }
]

Read a file

GET /v1/files/{id} returns the file with its content, in the same shape as Create a file.

A file the person uploaded in the Drive app may be larger than the 300,000 byte limit for text content; its response has no content. Reading such files from an app is not covered by these pages.

Update a file

PATCH /v1/files/{id} changes any of name, content, mime_type, tags and directory_id (to move it to another folder your grant covers). Send the version you last read as expected_version:

curl -X PATCH "$DRIVE/v1/files/9327802d-b5d8-42e7-a6d5-61d31ffaf600" "${AUTH[@]}" \
  -H "Content-Type: application/json" \
  -d '{"expected_version": 1, "content": "Apples\nPears\n"}'

200 OK:

{
  "content": "Apples\nPears\n",
  "content_hash": "sha256:85aec20b7cdcd332697e548f15fde71522f8aff36413f786e4a8261cc7676c35",
  "created_at": "2026-11-05T20:40:14.87202439Z",
  "directory_id": "6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f",
  "id": "9327802d-b5d8-42e7-a6d5-61d31ffaf600",
  "mime_type": "text/markdown",
  "name": "shopping.md",
  "owner_uid": "usr_7Hq2mV9cXk4tR1pB",
  "size_bytes": 13,
  "tags": [],
  "updated_at": "2026-11-05T20:40:15.219403584Z",
  "version": 2
}

If the file has changed since (someone else wrote version 2 first), the update is refused and nothing is written. Read the file again and retry. 409 Conflict:

{"error": "file version mismatch"}

Earlier versions

Each update keeps the previous version. GET /v1/files/{id}/revisions lists them, without content:

[
  {
    "content_hash": "sha256:d14cbe5383b698ced713c1325292e005a85a051cb10d969893d60fde2ec32c53",
    "directory_id": "6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f",
    "file_created_at": "2026-11-05T20:40:14.87202439Z",
    "file_id": "9327802d-b5d8-42e7-a6d5-61d31ffaf600",
    "file_updated_at": "2026-11-05T20:40:14.87202439Z",
    "mime_type": "text/markdown",
    "name": "shopping.md",
    "owner_uid": "usr_7Hq2mV9cXk4tR1pB",
    "preserved_at": "2026-11-05T20:40:15.219403584Z",
    "size_bytes": 7,
    "tags": [],
    "version": 1
  }
]

To bring one back, POST /v1/files/{id}/revisions/{version}/restore with the current version:

curl "$DRIVE/v1/files/9327802d-b5d8-42e7-a6d5-61d31ffaf600/revisions/1/restore" "${AUTH[@]}" \
  -H "Content-Type: application/json" -d '{"expected_current_version": 2}'

The restore is a new version (here 3) with the old content; it returns the file.

Trash and restore

POST /v1/files/{id}/archive (no body) moves a file to the person’s trash. It returns the file with archived_at and archived_by set:

{
  "archived_at": "2026-11-05T20:40:15.50659191Z",
  "archived_by": {
    "kind": "agent_run",
    "uid": "usr_7Hq2mV9cXk4tR1pB"
  },
  "content": "Apples\n",
  "content_hash": "sha256:d14cbe5383b698ced713c1325292e005a85a051cb10d969893d60fde2ec32c53",
  "created_at": "2026-11-05T20:40:14.87202439Z",
  "directory_id": "6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f",
  "id": "9327802d-b5d8-42e7-a6d5-61d31ffaf600",
  "mime_type": "text/markdown",
  "name": "shopping.md",
  "owner_uid": "usr_7Hq2mV9cXk4tR1pB",
  "size_bytes": 7,
  "tags": [],
  "updated_at": "2026-11-05T20:40:15.50659191Z",
  "version": 4
}

kind is agent_run when an app moved the file. GET /v1/files/archived lists the trashed files your grant covers, and POST /v1/files/{id}/restore (no body) takes one out of the trash.

Deleting

Apps can’t permanently delete files: DELETE /v1/files/{id} returns 403 to an app. Move the file to the trash; the person can delete it from there in the Drive app.