-
Notifications
You must be signed in to change notification settings - Fork 131
docs: add Walrus Console beta documentation #3540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
reemsabawi-mystenlabs
wants to merge
25
commits into
main
Choose a base branch
from
reem/console-docs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 9 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
f5ce251
docs: add Walrus Console beta documentation
reemsabawi-mystenlabs 9fd8972
docs: add Walrus Console to sidebar
reemsabawi-mystenlabs fc1d92f
docs: add Walrus Console to sidebar
reemsabawi-mystenlabs 4bbe6c0
docs: address Console docs review feedback
reemsabawi-mystenlabs c568910
docs: apply Sui style-guide audit fixes to Console docs
reemsabawi-mystenlabs 951f558
docs: use Prerequisites tab component in Console quickstart
reemsabawi-mystenlabs fe044de
docs: resolve remaining style-audit flags in Console docs
reemsabawi-mystenlabs 47a9582
docs: source Console quickstart code from walrus-harbor-quickstart
reemsabawi-mystenlabs 476d3fd
docs: address second-round Console docs review
reemsabawi-mystenlabs f40c791
docs(console): apply eng review corrections to beta availability claims
claude 18c4be6
Merge remote-tracking branch 'origin/main' into reem/console-docs
claude b9933e3
docs(console): style-guide pass over the console pages
claude 82b99db
docs(console): state the storage epoch duration and link the Network …
claude 6146e44
Merge remote-tracking branch 'origin/main' into reem/console-docs
claude 5975526
docs(console): active voice fixes flagged by the style gate
claude 338575d
docs(console): cut the datasets asset type
claude b86f405
docs(console): add the Console FAQ for the beta launch
claude 889800c
docs(console): active-voice fixes across the Console pages
claude a1e14dd
docs(console): correct the upload cap unit and firm up the free tier
claude 60e183c
docs(console): the MCP server needs both Console keys, not just the A…
claude 77acca3
docs(console): document the Console MCP server
claude 6e9ecca
docs(console): point at the Console URLs and drop the alpha framing
claude 40dcb11
docs(console): apply George's API-key flow review and reconcile the p…
claude f56b017
docs(console): name the API the Console developer API on the referenc…
claude 91db174
docs(console): a plain API key reveals both secrets
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,295 @@ | ||
| --- | ||
| title: API Reference | ||
| description: The Walrus Console external API surface for spaces, buckets, files, and Seal sponsorship, including authentication, conventions, and error codes. | ||
| keywords: [walrus console, api reference, spaces, buckets, files, seal, api keys] | ||
| --- | ||
|
|
||
| This reference covers the Walrus Console external API: the endpoints third-party developers use to manage spaces, buckets, and files, plus the [Seal](/docs/data-security) sponsorship endpoints that back private-bucket access control. | ||
|
|
||
| :::info | ||
|
|
||
| This documents the current Testnet surface. The API is in alpha and currently only available on Testnet at `https://api.testnet.harbor.walrus.xyz`. The endpoint structure might change before Mainnet GA. For a guided walkthrough of the full encrypted flow, start with the [Quick Start](./quickstart). For the product model behind these endpoints, see the [concepts and overview](./overview). | ||
|
|
||
| ::: | ||
|
|
||
| ## Authentication | ||
|
|
||
| Every request carries an API key as a bearer token: | ||
|
|
||
| ```http | ||
| Authorization: Bearer hbr_… | ||
| ``` | ||
|
|
||
| Mint keys through the Console web interface. Each key has one of two roles: | ||
|
|
||
| - `read_write` keys can change state: create and delete buckets, upload and delete files, and finalize private buckets. | ||
| - `read_only` keys can list, check status, and download only. Any write with a read-only key returns `403` with code `read_only_api_key`. | ||
|
|
||
| A request with no valid key returns `401`. A key without access to the target resource returns `403`. | ||
|
|
||
| ## Base URL and conventions | ||
|
|
||
| All paths are relative to the base URL and prefixed with `/api/v1`: | ||
|
|
||
| ``` | ||
| https://api.testnet.harbor.walrus.xyz | ||
| ``` | ||
|
|
||
| Request and response bodies are JSON unless noted (file upload uses `multipart/form-data`, and download returns a raw byte stream). Resource identifiers are UUIDs. | ||
|
|
||
| ### Pagination | ||
|
|
||
| List endpoints return an opaque cursor. Pass `limit` to set page size and `cursor` to fetch the next page. When there are no further results, the cursor field returns `null`. Bucket lists return the cursor as `next_cursor`; file lists return it under `pagination.nextCursor`. | ||
|
|
||
| ### Asynchronous operations | ||
|
|
||
| Upload and delete operations are asynchronous. Upload returns `202` with a file ID, then you poll the file status endpoint until the state is `completed`. Delete returns `204` immediately and releases storage after a background worker confirms the removal. | ||
|
|
||
| ## Errors | ||
|
|
||
| Error responses use the shape: | ||
|
|
||
| ```json | ||
| { "error": "Human-readable message", "code": "machine_readable_code" } | ||
| ``` | ||
|
|
||
| The `code` field is present when a machine-readable value applies. Common error codes include: | ||
|
|
||
| | Code | Meaning | | ||
| | --- | --- | | ||
| | `unauthorized` | Missing or invalid API key. | | ||
| | `read_only_api_key` | A write was attempted with a read-only key. | | ||
| | `api_key_registering` / `api_key_revoking` / `api_key_revoked` | The key is not currently usable. | | ||
| | `bucket_not_in_scope` | The key cannot access the target bucket. | | ||
| | `bucket_not_finalized` | The bucket has not completed the finalize step. | | ||
| | `mirror_missing_grant` | The onchain access grant has not yet mirrored into the access index. Retry. | | ||
| | `quota_exceeded` | The operation exceeds the plan or storage quota. | | ||
| | `payload_too_large` | The upload exceeds the size limit. | | ||
| | `bad_request` | The request failed validation. | | ||
| | `USED_NONCE` / `EXPIRED_TIMESTAMP` / `ADDRESS_MISMATCH` / `INVALID_CHALLENGE` | Wallet challenge errors, returned by the signature-authentication flow. | | ||
|
|
||
| Create-bucket requests that exceed a plan limit return `422` with a distinct shape: | ||
|
|
||
| ```json | ||
| { "code": "PLAN_LIMIT_EXCEEDED", "limit": "storage", "currentTier": "free" } | ||
| ``` | ||
|
|
||
| The `limit` value is one of `storage`, `users`, or `buckets`. | ||
|
|
||
| ## Spaces | ||
|
|
||
| A space is the top-level container for your data. Console creates a Personal Space at sign-up. | ||
|
|
||
| ### List spaces | ||
|
|
||
| `GET /api/v1/spaces` | ||
|
|
||
| Lists all spaces accessible to the authenticated user. | ||
|
|
||
| | Parameter | Location | Required | Description | | ||
| | --- | --- | --- | --- | | ||
| | `type` | query | No | Filter by space type: `personal` or `team`. | | ||
|
|
||
| Returns `200` with a `data` array of spaces. Each space includes `id`, `type`, `name`, `storage_used`, `storage_cap`, `bucket_count`, `role`, and `created_at`. Team Spaces also include `member_count`. | ||
|
|
||
| ### List buckets in a space | ||
|
|
||
| `GET /api/v1/spaces/{id}/buckets` | ||
|
|
||
| | Parameter | Location | Required | Description | | ||
| | --- | --- | --- | --- | | ||
| | `id` | path | Yes | Space UUID. | | ||
| | `limit` | query | No | Page size, 1 to 1000. Default 100. | | ||
| | `cursor` | query | No | Cursor from a previous page. | | ||
| | `q` | query | No | Case-insensitive substring match on bucket name. | | ||
| | `visibility` | query | No | Filter by `public` or `private`. | | ||
| | `sortField` | query | No | `name`, `date`, or `storage`. Default `date`. | | ||
| | `sortOrder` | query | No | `asc` or `desc`. Default `desc`. | | ||
|
|
||
| Returns `200` with `buckets` and `next_cursor`. | ||
|
|
||
| ### Create a bucket | ||
|
|
||
| `POST /api/v1/spaces/{id}/buckets` | ||
|
|
||
| Reserves a private bucket. This is the first step of the reserve, sign, and finalize handshake. In the current alpha, `scope` accepts `private` only. | ||
|
|
||
| Body: | ||
|
|
||
| ```json | ||
| { "name": "secrets", "scope": "private" } | ||
| ``` | ||
|
|
||
| Returns `201` with the reservation: | ||
|
|
||
| ```json | ||
| { | ||
| "bucket_id": "…", | ||
| "bytes": "<base64 sponsored Sui transaction>", | ||
| "digest": "…", | ||
| "state": "pending_policy" | ||
| } | ||
| ``` | ||
|
|
||
| Sign `bytes` locally with your service key, then call the finalize endpoint. The bucket stays in `pending_policy` and accepts no uploads until finalize succeeds. A name conflict returns `409`. A plan-limit breach returns `422`. See the [Quick Start](./quickstart) for the full signing flow. | ||
|
|
||
| ### List files in a space | ||
|
|
||
| `GET /api/v1/spaces/{id}/files` | ||
|
|
||
| Searches files across every bucket in the space. | ||
|
|
||
| | Parameter | Location | Required | Description | | ||
| | --- | --- | --- | --- | | ||
| | `id` | path | Yes | Space UUID. | | ||
| | `limit` | query | No | Page size, 1 to 100. Default 20. | | ||
| | `cursor` | query | No | Cursor from a previous page. | | ||
| | `q` | query | No | Case-insensitive substring match on file name. | | ||
| | `sortField` | query | No | `name`, `date`, `size`, or `type`. Default `date`. | | ||
| | `sortOrder` | query | No | `asc` or `desc`. Default `desc`. | | ||
|
|
||
| Returns `200` with `data` and a `pagination` object (`limit`, `hasMore`, `nextCursor`). | ||
|
|
||
| ## Buckets | ||
|
|
||
| A bucket holds files inside a space. Private buckets store [Seal](/docs/data-security) ciphertext only. | ||
|
|
||
| ### Get a bucket | ||
|
|
||
| `GET /api/v1/buckets/{id}` | ||
|
|
||
| Returns `200` with the bucket under `data`: `id`, `space_id`, `name`, `oyster_bucket_name`, `visibility`, `seal_policy_id`, `storage_used`, `created_at`, and `updated_at`. | ||
|
|
||
| ### Update a bucket | ||
|
|
||
| `PUT /api/v1/buckets/{id}` | ||
|
|
||
| | Field | Required | Description | | ||
| | --- | --- | --- | | ||
| | `name` | Yes | New bucket name, 1 to 100 characters in length. | | ||
| | `sealPolicyId` | No | Seal policy ID. Pass `null` to clear. | | ||
| | `visibility` | No | Immutable in v1. Changing it returns `403`. | | ||
|
|
||
| Returns `200` with the updated bucket (`id`, `name`, `visibility`, `updated_at`). A name conflict returns `409`. | ||
|
|
||
| ### Delete a bucket | ||
|
|
||
| `DELETE /api/v1/buckets/{id}?confirm=true` | ||
|
|
||
| Requires the `confirm=true` query parameter, and the bucket must be empty. Returns `204` with an `X-Deleted-Id` header. A missing confirmation, a validation error, or a non-empty bucket returns `400`. | ||
|
|
||
| ### Finalize a private bucket | ||
|
|
||
| `POST /api/v1/buckets/{id}/finalize` | ||
|
|
||
| Submits the signature over the reserved transaction bytes to activate a pending private bucket. | ||
|
|
||
| Body: | ||
|
|
||
| ```json | ||
| { "signature": "<base64 signature>" } | ||
| ``` | ||
|
|
||
| Returns `200`: | ||
|
|
||
| ```json | ||
| { "bucket_id": "…", "seal_policy_id": "…", "state": "active" } | ||
| ``` | ||
|
|
||
| `seal_policy_id` is the onchain bucket-policy object ID used by Seal for access checks. The bucket is now ready for uploads. | ||
|
|
||
| ### List files in a bucket | ||
|
|
||
| `GET /api/v1/buckets/{id}/files` | ||
|
|
||
| Takes the same `limit`, `cursor`, `q`, `sortField`, and `sortOrder` parameters as the space file listing. Returns `200` with `data` and `pagination`. | ||
|
|
||
| ### Upload a file | ||
|
|
||
| `POST /api/v1/buckets/{id}/files` | ||
|
|
||
| Uploads a file asynchronously using `multipart/form-data`. | ||
|
|
||
| | Field | Required | Description | | ||
| | --- | --- | --- | | ||
| | `file` | Yes | The file bytes. For private buckets, upload the Seal-encrypted object. | | ||
| | `name` | No | File name, up to 255 characters in length. | | ||
| | `metadata` | No | JSON object string persisted with the file. Maximum 8 KiB. | | ||
|
|
||
| Returns `202` with the file summary under `data`. Poll the status endpoint until the state is `completed`. | ||
|
|
||
| :::info | ||
|
|
||
| After finalize, the onchain access grant takes a few seconds to propagate to the access index. During this window, uploads fail with a `403` and the error code `mirror_missing_grant`. Retry every few seconds until the grant appears. | ||
|
|
||
| ::: | ||
|
|
||
| Other responses include `409` (bucket not finalized or duplicate file name), `413` (payload too large), `422` (quota exceeded), and `429` (rate limited). | ||
|
|
||
| ## Files | ||
|
|
||
| ### Get file metadata | ||
|
|
||
| `GET /api/v1/buckets/{id}/files/{fileId}` | ||
|
|
||
| Returns `200` with the file summary under `data`: `id`, `bucket_id`, `name`, `blob_id`, `oyster_object_id`, `size`, `mime_type`, `status`, `is_private`, `metadata`, `created_at`, `updated_at`, and `deleted_at`. | ||
|
|
||
| ### Delete a file | ||
|
|
||
| `DELETE /api/v1/buckets/{id}/files/{fileId}` | ||
|
|
||
| Marks the file as `deleting` and enqueues a background job to remove the underlying blob. Returns `204` immediately. Storage is released after the worker confirms the delete. Repeated calls for the same file ID are deduplicated. | ||
|
|
||
| ### Get upload status | ||
|
|
||
| `GET /api/v1/buckets/{id}/files/{fileId}/status` | ||
|
|
||
| Polls the state of an in-flight upload after the upload endpoint returns `202`. | ||
|
|
||
| Returns `200` with `data.state`, one of `queued`, `active`, `completed`, or `failed`. When the worker reports it, `data.progress` gives fractional progress from 0 to 1. When the state is `failed`, `data.error` includes a `code` and `message`. Once the job leaves the queue this endpoint returns `404`, which does not mean the upload failed. If you get a `404` after uploading, check the file metadata endpoint to confirm the final status before treating it as an error. | ||
|
|
||
| ### Download a file | ||
|
|
||
| `GET /api/v1/buckets/{id}/files/{fileId}/download` | ||
|
|
||
| Streams the raw file content with `Content-Type` and `Content-Disposition` headers. For a private bucket, this returns the Seal ciphertext, which you decrypt client-side. See the [Quick Start](./quickstart) for the decrypt flow. | ||
|
|
||
| A file in `deleting` or `deleted` status returns `423`. An unavailable blob stream returns `500`. | ||
|
|
||
| ## Seal sponsorship | ||
|
|
||
| These endpoints build and sponsor the onchain bucket-policy transactions that manage private access. Console sponsors the gas through [Enoki](https://docs.enoki.mystenlabs.com/), so your service key signs but does not need a token balance. They are typically driven through the SDK patterns shown in the [Quick Start](./quickstart). | ||
|
|
||
| ### Sponsor a transaction | ||
|
|
||
| `POST /api/v1/seal/sponsor` | ||
|
|
||
| Builds a sponsored bucket-policy transaction and returns the bytes to sign plus a digest to echo to the execute endpoint. The body's `kind` selects the operation: | ||
|
|
||
| | `kind` | Purpose | Additional fields | | ||
| | --- | --- | --- | | ||
| | `bucket_group_create` | Create a bucket access group. | `bucketId` | | ||
| | `grant_bucket_access` | Grant access to recipients. | `groupIds`, `recipientAddress`, `scope` (`read` or `readwrite`) | | ||
| | `share_admin` | Add an admin to a group. | `groupId`, `member` | | ||
| | `unshare` | Remove a member from a group. | `groupId`, `member` | | ||
| | `unshare_bucket_access` | Revoke a service signer's access. | `groupId`, `serviceSignerAddress` | | ||
|
|
||
| Returns `200` with `bytes` and `digest`. | ||
|
|
||
| ### Execute a sponsored transaction | ||
|
|
||
| `POST /api/v1/seal/sponsor/{digest}/execute` | ||
|
|
||
| Submits the signature over the sponsored bytes. Console broadcasts the transaction and returns the onchain digest. | ||
|
|
||
| | Parameter | Location | Required | Description | | ||
| | --- | --- | --- | --- | | ||
| | `digest` | path | Yes | The sponsor digest from the sponsor endpoint. | | ||
|
|
||
| Body: | ||
|
|
||
| ```json | ||
| { "signature": "<base64 signature>" } | ||
| ``` | ||
|
|
||
| Returns `200` with the onchain `digest`. An expired or unknown digest returns `404`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| --- | ||
| title: Authentication and Accounts | ||
| description: How Walrus Console sign-in works with Google and Apple through Sui zkLogin, how your Pearl wallet is provisioned, and how accounts stay separate per identity. | ||
| keywords: [walrus console, sign in, zklogin, pearl wallet, apple, google, accounts] | ||
| --- | ||
|
|
||
| Walrus Console uses the same kind of login you already know using Google or Apple; no wallet, no seed phrase, no crypto setup. Just sign in and start storing data. | ||
|
|
||
| :::info | ||
|
|
||
| Walrus Console is available on Mainnet through a closed, invite-only beta. It currently supports Google sign-in, and plans to support Apple soon. For the product model, see the [concepts and overview](./overview). | ||
|
reemsabawi-mystenlabs marked this conversation as resolved.
Outdated
|
||
|
|
||
| ::: | ||
|
|
||
| ## How sign-in works | ||
|
|
||
| Console uses Sui [zkLogin](https://docs.sui.io/concepts/cryptography/zklogin). You authenticate with an identity provider you already have, and Console derives a [Sui address](https://docs.sui.io/concepts/cryptography/transaction-auth/keys-addresses) from that identity without exposing your provider account onchain and without asking you to manage a private key. | ||
|
|
||
| ## Sign in with Google | ||
|
|
||
| 1. Visit the [Walrus Console app](https://testnet.harbor.walrus.xyz/). | ||
|
reemsabawi-mystenlabs marked this conversation as resolved.
Outdated
|
||
| 2. Choose **Continue with Google** and complete the Google sign-in. | ||
| 3. Console provisions your account and a [Personal Space](./overview#core-concepts-spaces-buckets-and-files), then takes you to the dashboard. | ||
|
|
||
| Apple sign-in joins soon and works the same way, deriving your Sui address from your Apple identity. It accepts Apple's private email relay, so you can use the **Hide My Email** option. | ||
|
reemsabawi-mystenlabs marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Your Pearl wallet | ||
|
|
||
| On first sign-in, Console silently provisions a Pearl wallet, the embedded wallet Console manages on your behalf, for your derived Sui address. This wallet holds the storage resources your data uses. Console manages the wallet and paying for transactions for you, so you do not need to fund it or sign transactions to get started. More advanced workflows require explicit signing steps. | ||
|
reemsabawi-mystenlabs marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Accounts stay separate per identity | ||
|
|
||
| :::warning | ||
|
|
||
| Each identity provider maps to a separate Console account and a separate Sui address. If you sign in with Google and later sign in with Apple, you get two independent accounts, not one merged account. Data stored under one is not visible under the other. | ||
|
|
||
| ::: | ||
|
|
||
| Console shows an account-separation notice the first time you sign in so this is clear before you store anything. Choose one provider and use it consistently. Linking multiple providers to a single account is planned for a later release. | ||
|
|
||
| ## Wallet sign-in | ||
|
|
||
| Signing in with an existing Sui wallet is planned for a later release. For now, sign in with Google or Apple through zkLogin. If you hold assets in a personal Sui wallet, note that data you store through Console lives under your zkLogin-derived address, which is separate from a wallet you connect later. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.