Drive
Preview Base URL: https://tj7hnhcvwir4n6rl5itdqut3mq0wdpke.lambda-url.us-east-1.on.aws
Overview
Drive keeps a person’s files and folders. The person works with them in the Drive app at https://drive.stackwell.tech, signing in with ChirpAuth. Apps reach them through Drive’s API, and only with a grant: a permission the person approves in Granite that names your app, the files it covers, and whether it may read, write, or both.
It is for developers of apps that keep a signed-in person’s files in that person’s own Drive rather than in their own database. The person can see everything your app writes, in the Drive app, next to their other files.
With a grant, an app can, within the files the grant covers:
- create text files, list them, and read them;
- update them, with a version check so two writers can’t overwrite each other;
- list a file’s earlier versions and restore one;
- move files to the trash and restore them.
An app cannot permanently delete a file (only the person can, in the Drive app), and cannot reach anything its grant doesn’t cover.
The person can export their Drive from the Drive app: one ZIP of every file
outside the trash, in every app’s area, with each file’s earlier versions,
their tables, the shared records they hold, the grants they gave apps, and
their activity log, with a manifest.json listing them.
What preview means here: Drive runs in production, and Stackwell’s own apps store people’s files in it. Its API is not declared stable: routes and fields can change without notice. Drive is not open to new apps yet; each app is enabled by hand, and there is no self-serve sign-up.
These pages cover the file routes an app uses with a grant. The generated reference also lists routes that Stackwell’s own services use (tables, records, calendars and others); they are not documented for outside apps.
Not yet:
- Sharing a file or folder with another person.
- Search.
- Writing files larger than 300,000 bytes from an app.
- Self-serve access for new apps.
Quickstart
This walks through the path an app takes: check Drive is up, get the person’s approval, then write and read a file in their Drive.
1. Check that Drive is reachable
No credentials needed:
curl -fsS https://tj7hnhcvwir4n6rl5itdqut3mq0wdpke.lambda-url.us-east-1.on.aws/health
{"service":"drive","status":"ok"}
Every other route needs credentials:
curl -sS https://tj7hnhcvwir4n6rl5itdqut3mq0wdpke.lambda-url.us-east-1.on.aws/v1/files | grep -Fx '{"error":"unauthorized"}'
2. What your app needs
- A ChirpAuth confidential client, so your server can get a ChirpAuth machine token.
- Stackwell’s go-ahead for that client to request the
drive.grantscope from ChirpAuth. Developers can’t turn this on themselves. - A way to file requests with Granite (an app credential or the same machine token); see Granite’s developer docs.
3. Ask the person for a folder
Pick a folder id for your app (any UUID), and file a Granite storage_grant
request for it, naming your machine token’s sub as requester_chirp_sub:
{
"request_type": "storage_grant",
"title": "Acme notes",
"summary": "Acme wants to keep your notes in a folder in your Drive.",
"requested_action": "read and write files",
"requested_resource": "storage:drive:drive:files:in:6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f",
"requested_scopes": ["drive.read", "drive.write"],
"requester_chirp_sub": "<your machine token's sub>"
}
Send the person to Granite to approve it. Once they have, reading the request
from Granite gives you its grant_id. The person may approve fewer scopes
than you asked for.
4. Get the person’s Drive context
When the person signs in to your app with ChirpAuth, ask for the scope
openid drive.grant. The token response then carries an access_token with
audience drive. This is the user context: it tells Drive which person is
using your app right now.
5. Write a file
Send your machine token, the grant id and the user context together.
curl https://tj7hnhcvwir4n6rl5itdqut3mq0wdpke.lambda-url.us-east-1.on.aws/v1/files \
-H "Authorization: Bearer $MACHINE_TOKEN" \
-H "x-granite-grant: $GRANT_ID" \
-H "x-drive-user-context: $USER_CONTEXT" \
-H "Content-Type: application/json" \
-d '{
"name": "shopping.md",
"content": "Apples\n",
"mime_type": "text/markdown",
"directory_id": "6f1c2a9e-4b7d-5e3a-9c8f-0d2e4a6b8c1f"
}'
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
}
If the person has no folder with that id yet, Drive creates it on your app’s first write and records that it belongs to your app.
6. Read it back
curl https://tj7hnhcvwir4n6rl5itdqut3mq0wdpke.lambda-url.us-east-1.on.aws/v1/files/9327802d-b5d8-42e7-a6d5-61d31ffaf600 \
-H "Authorization: Bearer $MACHINE_TOKEN" \
-H "x-granite-grant: $GRANT_ID" \
-H "x-drive-user-context: $USER_CONTEXT"
The response is the file as above. API examples covers listing, updating, versions and the trash.
Authentication
An app sends three things on every request: a ChirpAuth machine token as
Authorization: Bearer, the id of a Granite grant the person approved as
x-granite-grant, and the person’s user context (a ChirpAuth access token
with audience drive and scope drive.grant) as x-drive-user-context.
Drive checks all three, and asks Granite about the grant, on every request, so
a grant the person revokes stops working at once. People use the Drive app;
its sign-in is for that app only. Authentication has the
checks and what each grant covers.
API reference
The full endpoint list is in the generated API reference. API examples walks through the routes an app uses, with requests and responses.
Conventions shared by the routes these pages cover:
- Every path starts with
/v1/. - Request and response bodies are JSON; send
Content-Type: application/json. Unknown fields in a file body are refused. - Times are RFC 3339 in UTC. Ids are UUIDs.
- Every change to a file increases its
versionby one. Updates must name theversionthey expect. - Lists are not paged.
- There are no idempotency keys. Two creates with the same name in the same
folder can’t both succeed: the second gets
409.
Errors and limits
Errors are JSON, {"error": "<message>"}, except parsing errors (bad path,
bad JSON, unknown field, body too large), which are plain text and come before
authentication. Each person has a file count, folder count and storage limit,
shared by every app they use, and file content is capped at 300,000 bytes.
Errors and limits lists the status codes and the
numbers.
Data and privacy
Drive keeps a person’s files, their earlier versions, and a record of who changed what, until the person deletes them. Your app sees only what its grant covers, while the grant is active; the person sees everything. Revoking a grant leaves the files in the person’s Drive. Drive can read file contents: it is not end-to-end encrypted. Data and privacy says what is stored, who sees it, and what deleting does.