{
  "openapi": "3.1.0",
  "info": {
    "title": "Graphon storage API",
    "version": "0.1.0",
    "description": "JSON API for buckets and objects on the Graphon Storage host. Authenticate with a bearer API key or temporary key. Object bytes move through presigned S3 requests, or through any S3 tool with the same API key."
  },
  "paths": {
    "/v1/workspaces/{workspaceId}/buckets": {
      "get": {
        "tags": ["Buckets"],
        "operationId": "list_buckets",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Return only the bucket with this exact name."
            },
            "required": false,
            "description": "Return only the bucket with this exact name."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "A list of buckets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucketList"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Lists the buckets in the workspace. Pass name to find one bucket by its exact name. Role: viewer or higher.",
        "summary": "List buckets",
        "x-cli-example": "graphon buckets list"
      },
      "post": {
        "tags": ["Buckets"],
        "operationId": "create_bucket",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "One bucket.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucketEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          },
          "503": {
            "description": "The storage provider is busy or failed. Send the same request again after the Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The storage provider is busy or failed. Send the same request again after the Retry-After seconds."
                }
              }
            }
          }
        },
        "description": "Creates a bucket and returns it when it is active. Provider, location, and indexing are fixed when the bucket is created. A request that omits them gets gcp, the US multi-region, and indexing enabled. Tell the user which provider and location the bucket uses, and that other values are available. Role: editor or higher.",
        "summary": "Create a bucket",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBucketRequest"
              }
            }
          },
          "required": true
        },
        "x-cli-example": "graphon buckets create support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/bucket-name-availability": {
      "get": {
        "tags": ["Buckets"],
        "operationId": "check_bucket_name",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "The bucket name to check.",
              "examples": ["support-tickets"]
            },
            "required": true,
            "description": "The bucket name to check."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Whether a bucket name is free.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NameAvailability"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Returns whether a bucket name is valid and free. Names are case-sensitive and unique within this workspace. Role: viewer or higher.",
        "summary": "Check a bucket name",
        "x-cli-example": "graphon buckets availability --name support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}": {
      "get": {
        "tags": ["Buckets"],
        "operationId": "get_bucket",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "One bucket, with its usage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucketDetails"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Returns one bucket with its settings and usage. Role: viewer or higher.",
        "summary": "Get a bucket",
        "x-cli-example": "graphon buckets get support-tickets"
      },
      "patch": {
        "tags": ["Buckets"],
        "operationId": "update_bucket",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "if-match",
            "in": "header",
            "schema": {
              "type": "string",
              "description": "Required. The current bucket revision in quotes, for example \"3\". A missing revision returns 428. A stale revision returns 412.",
              "examples": ["\"3\""]
            },
            "required": false,
            "description": "Required. The current bucket revision in quotes, for example \"3\". A missing revision returns 428. A stale revision returns 412."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "One bucket.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Bucket"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          },
          "412": {
            "description": "The bucket revision changed. Reload and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket revision changed. Reload and retry."
                }
              }
            }
          },
          "428": {
            "description": "Send the bucket revision in If-Match.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "Send the bucket revision in If-Match."
                }
              }
            }
          }
        },
        "description": "Changes the name, permission, availability, or policy atomically. Send the current revision as a quoted If-Match header. Names are case-sensitive and unique within the workspace. Renaming preserves the bucket ID and stored objects. Update S3 paths after renaming. A missing field keeps its value. Role: editor or higher.",
        "summary": "Update a bucket",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBucketRequest"
              }
            }
          },
          "required": true
        },
        "x-cli-example": "graphon buckets update support-tickets --permission public-read"
      },
      "delete": {
        "tags": ["Buckets"],
        "operationId": "delete_bucket",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "confirmName",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "The exact current bucket name.",
              "examples": ["support-tickets"]
            },
            "required": true,
            "description": "The exact current bucket name."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success"
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Deletes an empty bucket. Send the exact bucket name as confirmName. The name is free again when the deletion is final. After that, the bucket cannot be restored. Role: editor or higher.",
        "summary": "Delete a bucket",
        "x-cli-example": "graphon buckets delete support-tickets --confirm-name support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/retry-provisioning": {
      "post": {
        "tags": ["Buckets"],
        "operationId": "retry_bucket_provisioning",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "One bucket.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucketEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          },
          "503": {
            "description": "The storage provider is busy or failed. Send the same request again after the Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The storage provider is busy or failed. Send the same request again after the Retry-After seconds."
                }
              }
            }
          }
        },
        "description": "Provisions a bucket again after it failed, and returns it when it is active. Role: editor or higher.",
        "summary": "Retry bucket provisioning",
        "x-cli-example": "graphon buckets retry support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/empty": {
      "post": {
        "tags": ["Buckets"],
        "operationId": "empty_bucket",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "The bucket and the job that changes it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["bucket", "job"],
                  "properties": {
                    "bucket": {
                      "$ref": "#/components/schemas/Bucket"
                    },
                    "job": {
                      "$ref": "#/components/schemas/Job"
                    }
                  },
                  "additionalProperties": false,
                  "description": "The bucket and the job that changes it.",
                  "title": "BucketJob"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Deletes every object in the bucket. Send the exact bucket name as confirmName. Objects under retention stay, and the call returns object_locked with their keys. Role: editor or higher.",
        "summary": "Empty a bucket",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmNameRequest"
              }
            }
          },
          "required": true
        },
        "x-cli-example": "graphon buckets empty support-tickets --confirm-name support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/restore": {
      "post": {
        "tags": ["Buckets"],
        "operationId": "restore_bucket",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "The bucket and the job that changes it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["bucket", "job"],
                  "properties": {
                    "bucket": {
                      "$ref": "#/components/schemas/Bucket"
                    },
                    "job": {
                      "$ref": "#/components/schemas/Job"
                    }
                  },
                  "additionalProperties": false,
                  "description": "The bucket and the job that changes it.",
                  "title": "BucketJob"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Restores a deleted bucket within its recovery window. Role: editor or higher.",
        "summary": "Restore a bucket",
        "x-cli-example": "graphon buckets restore support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/jobs/{jobId}": {
      "get": {
        "tags": ["Buckets"],
        "operationId": "get_job",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "jobId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The job id.",
              "examples": ["job_4b1d0c"]
            },
            "required": true,
            "description": "The job id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Background work for a bucket or an object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Returns the status of background work, such as an empty or a copy. Role: viewer or higher.",
        "summary": "Get a job",
        "x-cli-example": "graphon jobs get job_4b1d0c"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/objects": {
      "get": {
        "tags": ["Objects"],
        "operationId": "list_objects",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "prefix",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Return only keys that start with this text."
            },
            "required": false,
            "description": "Return only keys that start with this text."
          },
          {
            "name": "delimiter",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Group keys into prefixes at this character, usually \"/\"."
            },
            "required": false,
            "description": "Group keys into prefixes at this character, usually \"/\"."
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["key", "newest"],
              "description": "key (the default) lists in key order. newest lists the most recently written objects first. It takes no delimiter."
            },
            "required": false,
            "description": "key (the default) lists in key order. newest lists the most recently written objects first. It takes no delimiter."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "The nextCursor from the previous page."
            },
            "required": false,
            "description": "The nextCursor from the previous page."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "The most items on one page, from 1 to 1000. A prefix counts as one item. The default is 1000.",
              "pattern": "^[1-9][0-9]{0,3}$"
            },
            "required": false,
            "description": "The most items on one page, from 1 to 1000. A prefix counts as one item. The default is 1000."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "One page of objects.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectPage"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Lists live objects in key order, one page at a time. Pass delimiter \"/\" to group keys into prefixes, or sort=newest to list the most recent writes first. Role: viewer or higher.",
        "summary": "List objects",
        "x-cli-example": "graphon objects list support-tickets --prefix incidents/"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/objects/{keyToken}": {
      "get": {
        "tags": ["Objects"],
        "operationId": "get_object_metadata",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "keyToken",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The object key, base64url-encoded without padding.",
              "examples": ["aW5jaWRlbnRzL2NoZWNrb3V0LXRpbWVvdXQuanNvbg"]
            },
            "required": true,
            "description": "The object key, base64url-encoded without padding."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "One object version, with its metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObjectDetails"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Returns the live version of one object without its bytes: its size, type, checksums, indexing status, and its metadata (the x-amz-meta-* headers it was written with). Role: viewer or higher.",
        "summary": "Get object metadata",
        "x-cli-example": "graphon objects stat support-tickets incidents/checkout-timeout.json"
      },
      "delete": {
        "tags": ["Objects"],
        "operationId": "delete_object",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "keyToken",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The object key, base64url-encoded without padding.",
              "examples": ["aW5jaWRlbnRzL2NoZWNrb3V0LXRpbWVvdXQuanNvbg"]
            },
            "required": true,
            "description": "The object key, base64url-encoded without padding."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "What a delete removed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteObjectResult"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Deletes one object. The deleted version stays recoverable for the bucket recovery window. Role: editor or higher.",
        "summary": "Delete an object",
        "x-cli-example": "graphon objects delete support-tickets incidents/checkout-timeout.json"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/objects/{keyToken}/versions": {
      "get": {
        "tags": ["Objects"],
        "operationId": "list_object_versions",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "keyToken",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The object key, base64url-encoded without padding.",
              "examples": ["aW5jaWRlbnRzL2NoZWNrb3V0LXRpbWVvdXQuanNvbg"]
            },
            "required": true,
            "description": "The object key, base64url-encoded without padding."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The versions of one object.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionList"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Lists the live versions and delete markers of one object, newest first. Role: viewer or higher.",
        "summary": "List object versions",
        "x-cli-example": "graphon objects versions support-tickets incidents/checkout-timeout.json"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/index-status": {
      "get": {
        "tags": ["Objects"],
        "operationId": "get_bucket_index_status",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "filter",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["unfinished", "failed", "unsupported"],
              "description": "unfinished (the default): versions that are not indexed yet, in the order they will finish. failed or unsupported: those versions, in key order."
            },
            "required": false,
            "description": "unfinished (the default): versions that are not indexed yet, in the order they will finish. failed or unsupported: those versions, in key order."
          },
          {
            "name": "prefix",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Return only keys that start with this text."
            },
            "required": false,
            "description": "Return only keys that start with this text."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "The nextCursor from the previous page."
            },
            "required": false,
            "description": "The nextCursor from the previous page."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "The most versions to return for one page, from 1 to 1000. The default is 100.",
              "pattern": "^[1-9][0-9]{0,3}$"
            },
            "required": false,
            "description": "The most versions to return for one page, from 1 to 1000. The default is 100."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The indexing status of a bucket: its counts and one page of its versions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucketIndexStatus"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Returns the indexing progress of a bucket: counts by state, and one page of versions. The default page lists the versions that are not indexed yet, in the order they will finish. Filter failed or unsupported to see why versions are not searchable. A bucket with indexing disabled fails with indexing_disabled. Role: viewer or higher.",
        "summary": "Get bucket index status",
        "x-cli-example": "graphon buckets index-status support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/objects/{keyToken}/restore": {
      "post": {
        "tags": ["Objects"],
        "operationId": "restore_object",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "keyToken",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The object key, base64url-encoded without padding.",
              "examples": ["aW5jaWRlbnRzL2NoZWNrb3V0LXRpbWVvdXQuanNvbg"]
            },
            "required": true,
            "description": "The object key, base64url-encoded without padding."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "The job that does the work.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["job"],
                  "properties": {
                    "job": {
                      "$ref": "#/components/schemas/Job"
                    }
                  },
                  "additionalProperties": false,
                  "description": "The job that does the work.",
                  "title": "JobEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          },
          "410": {
            "description": "The item is gone, such as a recovery copy whose recovery period ended.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The item is gone, such as a recovery copy whose recovery period ended."
                }
              }
            }
          }
        },
        "description": "Restores a deleted or replaced version from recovery. Get the recoveryId from the recovery list of the bucket. Role: editor or higher.",
        "summary": "Restore an object",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestoreObjectRequest"
              }
            }
          },
          "required": true
        },
        "x-cli-example": "graphon objects restore support-tickets incidents/checkout-timeout.json --recovery-id <recoveryId>"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/objects/{keyToken}/copy": {
      "post": {
        "tags": ["Objects"],
        "operationId": "copy_object",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          },
          {
            "name": "keyToken",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The object key, base64url-encoded without padding.",
              "examples": ["aW5jaWRlbnRzL2NoZWNrb3V0LXRpbWVvdXQuanNvbg"]
            },
            "required": true,
            "description": "The object key, base64url-encoded without padding."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "The job that does the work.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["job"],
                  "properties": {
                    "job": {
                      "$ref": "#/components/schemas/Job"
                    }
                  },
                  "additionalProperties": false,
                  "description": "The job that does the work.",
                  "title": "JobEnvelope"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          },
          "503": {
            "description": "The storage provider is busy or failed. Send the same request again after the Retry-After seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The storage provider is busy or failed. Send the same request again after the Retry-After seconds."
                }
              }
            }
          }
        },
        "description": "Copies an object to another key in the same bucket. Role: editor or higher.",
        "summary": "Copy an object",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopyObjectRequest"
              }
            }
          },
          "required": true
        },
        "x-cli-example": "graphon objects copy support-tickets a.json --destination-key b.json"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/presign": {
      "post": {
        "tags": ["Objects"],
        "operationId": "presign_object_request",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "One presigned S3 request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PresignResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          },
          "413": {
            "description": "One request cannot carry this many bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "One request cannot carry this many bytes."
                }
              }
            }
          }
        },
        "description": "Returns one presigned S3 request for one object key. Send it before expiresAt, with the returned headers exactly. Operations other than GetObject need the editor role. Role: viewer or higher.",
        "summary": "Presign an S3 request",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PresignRequest"
              }
            }
          },
          "required": true
        },
        "x-cli-example": "graphon objects put support-tickets incidents/checkout-timeout.json --file ./checkout-timeout.json"
      }
    },
    "/v1/workspaces/{workspaceId}/bucket-summary": {
      "get": {
        "tags": ["Insights"],
        "operationId": "get_bucket_summary",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every bucket in the workspace, with its usage and indexing counts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BucketSummaryList"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Returns every bucket in the workspace with its usage and indexing counts, in one call. A bucket that is not active, or that could not be read, has null usage and index. A bucket with indexing disabled has null index. Role: viewer or higher.",
        "summary": "Get the bucket summary"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/usage": {
      "get": {
        "tags": ["Insights"],
        "operationId": "get_bucket_usage",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Storage used by one bucket.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Returns the bytes and objects that one bucket stores. Role: viewer or higher.",
        "summary": "Get bucket usage",
        "x-cli-example": "graphon buckets usage support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/recovery": {
      "get": {
        "tags": ["Insights"],
        "operationId": "list_bucket_recovery",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Recovery copies in one bucket.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecoveryList"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Lists deleted or replaced versions that can still be restored. Role: viewer or higher.",
        "summary": "List bucket recovery",
        "x-cli-example": "graphon buckets recovery support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/activity": {
      "get": {
        "tags": ["Insights"],
        "operationId": "list_bucket_activity",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Recent changes to one bucket made through the JSON API, the app, the CLI, or MCP. S3-protocol writes and deletes are not recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityList"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Lists recent changes in one bucket, newest first. Role: viewer or higher.",
        "summary": "List bucket activity",
        "x-cli-example": "graphon buckets activity support-tickets"
      }
    },
    "/v1/workspaces/{workspaceId}/buckets/{bucketId}/metrics": {
      "get": {
        "tags": ["Insights"],
        "operationId": "get_bucket_metrics",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The workspace id.",
              "examples": ["wspq7ws2np5l8z4"]
            },
            "required": true,
            "description": "The workspace id."
          },
          {
            "name": "bucketId",
            "in": "path",
            "schema": {
              "type": "string",
              "description": "The bucket id.",
              "examples": ["bktA1b2C3d4E5"]
            },
            "required": true,
            "description": "The bucket id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Storage used by one bucket.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "400": {
            "description": "The request body, query, or path is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The request body, query, or path is invalid."
                }
              }
            }
          },
          "401": {
            "description": "The bearer key is missing, invalid, expired, or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bearer key is missing, invalid, expired, or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is valid, but its role or workspace does not allow the action.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The key is valid, but its role or workspace does not allow the action."
                }
              }
            }
          },
          "404": {
            "description": "The bucket, object, or job does not exist, or this key cannot see it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The bucket, object, or job does not exist, or this key cannot see it."
                }
              }
            }
          },
          "409": {
            "description": "The change conflicts with the bucket state, such as a bucket that is not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/StorageError"
                    }
                  ],
                  "description": "The change conflicts with the bucket state, such as a bucket that is not active yet."
                }
              }
            }
          }
        },
        "description": "Returns storage metrics for one bucket. Role: viewer or higher.",
        "summary": "Get bucket metrics",
        "x-cli-example": "graphon buckets metrics support-tickets"
      }
    }
  },
  "components": {
    "schemas": {
      "BucketList": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Bucket"
            },
            "description": "The buckets."
          }
        },
        "additionalProperties": false,
        "description": "A list of buckets.",
        "title": "BucketList",
        "examples": [
          {
            "items": [
              {
                "id": "bktA1b2C3d4E5",
                "workspaceId": "wspq7ws2np5l8z4",
                "name": "support-tickets",
                "provider": "gcp",
                "location": "us-central1",
                "storageClass": "standard",
                "permission": "private",
                "phase": "active",
                "availability": "online",
                "indexing": "enabled",
                "objectCount": 12,
                "revision": 1,
                "createdAt": "2026-10-01T12:00:00.000Z",
                "policy": {}
              }
            ]
          }
        ]
      },
      "Bucket": {
        "type": "object",
        "required": [
          "id",
          "workspaceId",
          "name",
          "provider",
          "location",
          "storageClass",
          "permission",
          "phase",
          "availability",
          "indexing",
          "objectCount",
          "revision",
          "createdAt",
          "policy"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "The bucket id."
          },
          "workspaceId": {
            "type": "string",
            "description": "The workspace id."
          },
          "name": {
            "type": "string",
            "description": "The bucket name. S3 tools use it."
          },
          "provider": {
            "type": "string",
            "description": "The storage provider: gcp or r2."
          },
          "location": {
            "type": "string",
            "description": "The provider region."
          },
          "storageClass": {
            "type": "string",
            "description": "The storage class."
          },
          "permission": {
            "type": "string",
            "enum": ["private", "public-read"],
            "description": "Who can read objects: private, or public-read for anonymous GET and HEAD."
          },
          "phase": {
            "type": "string",
            "description": "provisioning, active, provisioning_failed, or deleted. Most routes need active."
          },
          "availability": {
            "type": "string",
            "enum": ["online", "offline"],
            "description": "An offline bucket rejects reads and writes."
          },
          "indexing": {
            "type": "string",
            "enum": ["enabled", "disabled"],
            "description": "Whether Graphon indexes the objects so that you can search and query them. Fixed when the bucket is created."
          },
          "objectCount": {
            "type": "number",
            "description": "The number of live objects."
          },
          "revision": {
            "type": "number",
            "description": "The bucket revision."
          },
          "createdAt": {
            "type": "string",
            "description": "When the bucket was created, in UTC."
          },
          "policy": {
            "type": "object",
            "required": [],
            "properties": {},
            "additionalProperties": {
              "$id": "/schemas/unknown",
              "title": "unknown"
            },
            "description": "Bucket policy settings, such as versioning and retention."
          }
        },
        "additionalProperties": false,
        "description": "One bucket.",
        "title": "Bucket",
        "examples": [
          {
            "id": "bktA1b2C3d4E5",
            "workspaceId": "wspq7ws2np5l8z4",
            "name": "support-tickets",
            "provider": "gcp",
            "location": "us-central1",
            "storageClass": "standard",
            "permission": "private",
            "phase": "active",
            "availability": "online",
            "indexing": "enabled",
            "objectCount": 12,
            "revision": 1,
            "createdAt": "2026-10-01T12:00:00.000Z",
            "policy": {}
          }
        ]
      },
      "StorageError": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "retryable"],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable error token, such as not_found or bucket_not_ready."
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation."
              },
              "retained": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": ["key", "retainUntil"],
                  "properties": {
                    "key": {
                      "type": "string",
                      "description": "The object key."
                    },
                    "retainUntil": {
                      "type": "string",
                      "description": "When the retention ends, in UTC."
                    }
                  },
                  "additionalProperties": false
                },
                "description": "For object_locked: the objects that retention kept."
              },
              "retryable": {
                "type": "boolean",
                "description": "True when the same request can work later with no change. Then the response also has Retry-After and details.retryAfterSeconds. False when the same request gets the same error."
              },
              "details": {
                "type": "object",
                "required": [],
                "properties": {
                  "retryAfterSeconds": {
                    "type": "integer",
                    "description": "For a retryable error: the seconds to wait before the same request. The Retry-After header has the same value.",
                    "title": "int"
                  }
                },
                "additionalProperties": false,
                "description": "More about the error. Each field is optional."
              }
            },
            "additionalProperties": false,
            "description": "Machine-readable failure."
          }
        },
        "additionalProperties": false,
        "description": "Error body returned by the storage API.",
        "title": "StorageError"
      },
      "NameAvailability": {
        "type": "object",
        "required": ["available", "reason"],
        "properties": {
          "available": {
            "type": "boolean",
            "description": "Whether the name can be used."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": ["invalid", "unavailable"]
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the name cannot be used, or null."
          }
        },
        "additionalProperties": false,
        "description": "Whether a bucket name is free.",
        "title": "NameAvailability",
        "examples": [
          {
            "available": true,
            "reason": null
          }
        ]
      },
      "CreateBucketRequest": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": {
            "type": "string",
            "description": "A case-sensitive name unique within this workspace. Use 1 to 255 ASCII letters, digits, periods, underscores, or hyphens. The exact names . and .. are invalid.",
            "examples": ["support-tickets"]
          },
          "provider": {
            "type": "string",
            "description": "gcp or r2. The default is gcp. It is fixed when the bucket is created.",
            "examples": ["gcp"]
          },
          "location": {
            "type": "string",
            "description": "The provider region, for example us-central1. The default is the US multi-region of the provider. It is fixed when the bucket is created.",
            "examples": ["us-central1"]
          },
          "indexing": {
            "type": "string",
            "enum": ["enabled", "disabled"],
            "description": "Whether Graphon indexes the objects so that you can search and query them. Fixed when the bucket is created."
          },
          "storageClass": {
            "type": "string",
            "description": "The storage class. The default is standard."
          },
          "permission": {
            "type": "string",
            "enum": ["private", "public-read"],
            "description": "Who can read objects: private, or public-read for anonymous GET and HEAD."
          },
          "policy": {
            "type": "object",
            "required": [],
            "properties": {},
            "additionalProperties": {
              "$id": "/schemas/unknown",
              "title": "unknown"
            },
            "description": "Bucket policy settings, such as versioning and retention."
          }
        },
        "additionalProperties": false,
        "description": "A new bucket.",
        "title": "CreateBucketRequest",
        "examples": [
          {
            "name": "support-tickets",
            "provider": "gcp",
            "location": "us-central1",
            "indexing": "enabled"
          }
        ]
      },
      "BucketEnvelope": {
        "type": "object",
        "required": ["bucket"],
        "properties": {
          "bucket": {
            "$ref": "#/components/schemas/Bucket"
          }
        },
        "additionalProperties": false,
        "description": "One bucket.",
        "title": "BucketEnvelope"
      },
      "BucketDetails": {
        "type": "object",
        "required": [
          "id",
          "workspaceId",
          "name",
          "provider",
          "location",
          "storageClass",
          "permission",
          "phase",
          "availability",
          "indexing",
          "objectCount",
          "revision",
          "createdAt",
          "policy",
          "usage"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "The bucket id."
          },
          "workspaceId": {
            "type": "string",
            "description": "The workspace id."
          },
          "name": {
            "type": "string",
            "description": "The bucket name. S3 tools use it."
          },
          "provider": {
            "type": "string",
            "description": "The storage provider: gcp or r2."
          },
          "location": {
            "type": "string",
            "description": "The provider region."
          },
          "storageClass": {
            "type": "string",
            "description": "The storage class."
          },
          "permission": {
            "type": "string",
            "enum": ["private", "public-read"],
            "description": "Who can read objects: private, or public-read for anonymous GET and HEAD."
          },
          "phase": {
            "type": "string",
            "description": "provisioning, active, provisioning_failed, or deleted. Most routes need active."
          },
          "availability": {
            "type": "string",
            "enum": ["online", "offline"],
            "description": "An offline bucket rejects reads and writes."
          },
          "indexing": {
            "type": "string",
            "enum": ["enabled", "disabled"],
            "description": "Whether Graphon indexes the objects so that you can search and query them. Fixed when the bucket is created."
          },
          "objectCount": {
            "type": "number",
            "description": "The number of live objects."
          },
          "revision": {
            "type": "number",
            "description": "The bucket revision."
          },
          "createdAt": {
            "type": "string",
            "description": "When the bucket was created, in UTC."
          },
          "policy": {
            "type": "object",
            "required": [],
            "properties": {},
            "additionalProperties": {
              "$id": "/schemas/unknown",
              "title": "unknown"
            },
            "description": "Bucket policy settings, such as versioning and retention."
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        },
        "additionalProperties": false,
        "description": "One bucket, with its usage.",
        "title": "BucketDetails"
      },
      "Usage": {
        "type": "object",
        "required": ["liveBytes", "recoveryBytes", "objectCount"],
        "properties": {
          "liveBytes": {
            "type": "string",
            "description": "Bytes in live versions, as a decimal string."
          },
          "recoveryBytes": {
            "type": "string",
            "description": "Bytes kept for recovery, as a decimal string."
          },
          "objectCount": {
            "type": "number",
            "description": "The number of live objects."
          }
        },
        "additionalProperties": false,
        "description": "Storage used by one bucket.",
        "title": "Usage",
        "examples": [
          {
            "liveBytes": "2048",
            "recoveryBytes": "0",
            "objectCount": 12
          }
        ]
      },
      "UpdateBucketRequest": {
        "type": "object",
        "required": [],
        "properties": {
          "name": {
            "type": "string",
            "description": "A case-sensitive name unique within this workspace. Use 1 to 255 ASCII letters, digits, periods, underscores, or hyphens. The exact names . and .. are invalid."
          },
          "permission": {
            "type": "string",
            "enum": ["private", "public-read"],
            "description": "Who can read objects: private, or public-read for anonymous GET and HEAD."
          },
          "availability": {
            "type": "string",
            "enum": ["online", "offline"],
            "description": "An offline bucket rejects reads and writes."
          },
          "policy": {
            "type": "object",
            "required": [],
            "properties": {},
            "additionalProperties": {
              "$id": "/schemas/unknown",
              "title": "unknown"
            },
            "description": "Bucket policy settings, such as versioning and retention."
          }
        },
        "additionalProperties": false,
        "description": "Bucket settings to change. A missing field keeps its value.",
        "title": "UpdateBucketRequest",
        "examples": [
          {
            "name": "Support.Tickets_2026"
          },
          {
            "permission": "public-read"
          }
        ]
      },
      "ConfirmNameRequest": {
        "type": "object",
        "required": ["confirmName"],
        "properties": {
          "confirmName": {
            "type": "string",
            "description": "The exact current bucket name.",
            "examples": ["support-tickets"]
          }
        },
        "additionalProperties": false,
        "description": "Confirms a destructive change by naming the bucket.",
        "title": "ConfirmNameRequest",
        "examples": [
          {
            "confirmName": "support-tickets"
          }
        ]
      },
      "Job": {
        "type": "object",
        "required": ["id", "kind", "status", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "The job id."
          },
          "kind": {
            "type": "string",
            "description": "What the job does."
          },
          "status": {
            "type": "string",
            "description": "pending, running, succeeded, or failed."
          },
          "createdAt": {
            "type": "string",
            "description": "When the job was created, in UTC."
          },
          "updatedAt": {
            "type": "string",
            "description": "When the job last changed, in UTC."
          }
        },
        "additionalProperties": false,
        "description": "Background work for a bucket or an object.",
        "title": "Job"
      },
      "ObjectPage": {
        "type": "object",
        "required": ["items", "nextCursor"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/ObjectSummary"
                },
                {
                  "$ref": "#/components/schemas/CommonPrefix"
                }
              ]
            },
            "description": "Objects in key order, then the prefixes."
          },
          "nextCursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as cursor to read the next page, or null on the last page. A page can hold fewer items than limit, even none, before the last page."
          }
        },
        "additionalProperties": false,
        "description": "One page of objects.",
        "title": "ObjectPage"
      },
      "ObjectSummary": {
        "type": "object",
        "required": [
          "kind",
          "id",
          "bucketId",
          "key",
          "versionId",
          "sizeBytes",
          "contentType",
          "etag",
          "createdAt",
          "revision",
          "retainUntil",
          "checksums",
          "indexing"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["object"]
          },
          "id": {
            "type": "string",
            "description": "The version id."
          },
          "bucketId": {
            "type": "string",
            "description": "The bucket id."
          },
          "key": {
            "type": "string",
            "description": "The object key."
          },
          "versionId": {
            "type": "string",
            "description": "The version id."
          },
          "sizeBytes": {
            "type": "string",
            "description": "The size in bytes, as a decimal string."
          },
          "contentType": {
            "type": "string",
            "description": "The content type."
          },
          "etag": {
            "type": "string",
            "description": "The entity tag."
          },
          "createdAt": {
            "type": "string",
            "description": "When the version was written, in UTC."
          },
          "revision": {
            "type": "number",
            "description": "The metadata revision."
          },
          "retainUntil": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When retention ends, in UTC, or null."
          },
          "checksums": {
            "type": "object",
            "required": [],
            "properties": {},
            "additionalProperties": {
              "type": "string"
            },
            "description": "Stored checksums by algorithm."
          },
          "indexing": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IndexStatus"
              },
              {
                "type": "null"
              }
            ],
            "description": "The indexing status, or null when the bucket does not index or search no longer uses this version."
          }
        },
        "additionalProperties": false,
        "description": "One object version.",
        "title": "ObjectSummary"
      },
      "IndexStatus": {
        "type": "object",
        "required": [
          "state",
          "stage",
          "since",
          "retries",
          "error",
          "progress",
          "timeline",
          "searchable"
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "preparing",
              "sending",
              "queued",
              "indexing",
              "ready",
              "failed",
              "unsupported"
            ],
            "description": "Where the version is on its way into search: preparing, sending, queued, or indexing while unfinished, then ready, failed, or unsupported."
          },
          "stage": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "waiting_to_copy",
                  "copying",
                  "engine_queued",
                  "checking_source",
                  "core_queued",
                  "processing",
                  "building_index"
                ],
                "description": "The step inside an unfinished state: waiting_to_copy or copying (preparing); engine_queued, checking_source, or core_queued (queued); processing or building_index (indexing)."
              },
              {
                "type": "null"
              }
            ],
            "description": "The step inside the state, or null when the state has no finer step."
          },
          "since": {
            "type": "string",
            "description": "When this state started, in UTC."
          },
          "retries": {
            "type": "number",
            "description": "Failed tries of the current step."
          },
          "error": {
            "anyOf": [
              {
                "type": "object",
                "required": ["code", "message", "retrying"],
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "A stable error token."
                  },
                  "message": {
                    "type": "string",
                    "description": "A readable reason."
                  },
                  "retrying": {
                    "type": "boolean",
                    "description": "True when Graphon tries the step again by itself."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the version failed or is not supported, or the last error of a retried step."
          },
          "progress": {
            "anyOf": [
              {
                "type": "object",
                "required": ["doneBytes", "totalBytes"],
                "properties": {
                  "doneBytes": {
                    "type": "string",
                    "description": "Bytes copied, as a decimal string."
                  },
                  "totalBytes": {
                    "type": "string",
                    "description": "All bytes, as a decimal string."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "The copy progress while preparing, or null."
          },
          "timeline": {
            "type": "object",
            "required": ["writtenAt", "copiedAt", "sentAt", "startedAt", "finishedAt"],
            "properties": {
              "writtenAt": {
                "type": "string",
                "description": "When the version was written, in UTC."
              },
              "copiedAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When the version was prepared for indexing, in UTC, or null."
              },
              "sentAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When the index accepted the version, in UTC, or null."
              },
              "startedAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When processing started, in UTC, or null."
              },
              "finishedAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When the version became ready, failed, or unsupported, in UTC, or null."
              }
            },
            "additionalProperties": false
          },
          "searchable": {
            "anyOf": [
              {
                "type": "object",
                "required": ["versionId", "createdAt"],
                "properties": {
                  "versionId": {
                    "type": "string",
                    "description": "The searchable version."
                  },
                  "createdAt": {
                    "type": "string",
                    "description": "When it was written, in UTC."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "The version that search returns for this key now: this version when it is ready, an older one while this one is unfinished or failed, or null."
          }
        },
        "additionalProperties": false,
        "description": "The indexing status of one object version.",
        "title": "IndexStatus"
      },
      "CommonPrefix": {
        "type": "object",
        "required": ["kind", "prefix"],
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["prefix"]
          },
          "prefix": {
            "type": "string",
            "description": "A key prefix that groups more objects."
          }
        },
        "additionalProperties": false,
        "description": "A group of keys under one prefix.",
        "title": "CommonPrefix"
      },
      "ObjectDetails": {
        "type": "object",
        "required": [
          "kind",
          "id",
          "bucketId",
          "key",
          "versionId",
          "sizeBytes",
          "contentType",
          "etag",
          "createdAt",
          "revision",
          "retainUntil",
          "checksums",
          "indexing",
          "metadata"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["object"]
          },
          "id": {
            "type": "string",
            "description": "The version id."
          },
          "bucketId": {
            "type": "string",
            "description": "The bucket id."
          },
          "key": {
            "type": "string",
            "description": "The object key."
          },
          "versionId": {
            "type": "string",
            "description": "The version id."
          },
          "sizeBytes": {
            "type": "string",
            "description": "The size in bytes, as a decimal string."
          },
          "contentType": {
            "type": "string",
            "description": "The content type."
          },
          "etag": {
            "type": "string",
            "description": "The entity tag."
          },
          "createdAt": {
            "type": "string",
            "description": "When the version was written, in UTC."
          },
          "revision": {
            "type": "number",
            "description": "The metadata revision."
          },
          "retainUntil": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When retention ends, in UTC, or null."
          },
          "checksums": {
            "type": "object",
            "required": [],
            "properties": {},
            "additionalProperties": {
              "type": "string"
            },
            "description": "Stored checksums by algorithm."
          },
          "indexing": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IndexStatus"
              },
              {
                "type": "null"
              }
            ],
            "description": "The indexing status, or null when the bucket does not index or search no longer uses this version."
          },
          "metadata": {
            "type": "object",
            "required": [],
            "properties": {},
            "additionalProperties": {
              "type": "string"
            },
            "description": "The metadata of the version, by key: the x-amz-meta-<key> headers it was written with. A metadata field of the bucket can filter search on a key."
          }
        },
        "additionalProperties": false,
        "description": "One object version, with its metadata.",
        "title": "ObjectDetails"
      },
      "VersionList": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObjectSummary"
            },
            "description": "Versions, newest first."
          }
        },
        "additionalProperties": false,
        "description": "The versions of one object.",
        "title": "VersionList"
      },
      "BucketIndexStatus": {
        "type": "object",
        "required": ["summary", "items", "nextCursor"],
        "properties": {
          "summary": {
            "type": "object",
            "required": [
              "status",
              "counts",
              "olderVersionSearchable",
              "oldestUnfinishedSince",
              "activityByHour",
              "activityByDay",
              "lastReadyAt"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": ["empty", "indexing", "ready", "degraded", "failed"],
                "description": "empty: no live object. indexing: something unfinished and nothing ready. ready: something ready and nothing failed. degraded: something ready and something failed. failed: objects exist and none is ready."
              },
              "counts": {
                "type": "object",
                "required": [
                  "preparing",
                  "sending",
                  "queued",
                  "indexing",
                  "ready",
                  "failed",
                  "unsupported"
                ],
                "properties": {
                  "preparing": {
                    "type": "number",
                    "description": "Live versions that are preparing."
                  },
                  "sending": {
                    "type": "number",
                    "description": "Live versions that are sending."
                  },
                  "queued": {
                    "type": "number",
                    "description": "Live versions that are queued."
                  },
                  "indexing": {
                    "type": "number",
                    "description": "Live versions that are indexing."
                  },
                  "ready": {
                    "type": "number",
                    "description": "Live versions that are ready."
                  },
                  "failed": {
                    "type": "number",
                    "description": "Live versions that are failed."
                  },
                  "unsupported": {
                    "type": "number",
                    "description": "Live versions that are unsupported."
                  }
                },
                "additionalProperties": false
              },
              "olderVersionSearchable": {
                "type": "number",
                "description": "Live keys whose search still returns an older version."
              },
              "oldestUnfinishedSince": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When the longest-waiting unfinished version started its state, in UTC, or null."
              },
              "activityByHour": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": ["hour", "ready", "failed"],
                  "properties": {
                    "hour": {
                      "type": "string",
                      "description": "The start of the UTC hour, such as 2026-10-20T14:00:00.000Z."
                    },
                    "ready": {
                      "type": "number",
                      "description": "Live versions that became ready in this hour."
                    },
                    "failed": {
                      "type": "number",
                      "description": "Live versions that failed in this hour."
                    }
                  },
                  "additionalProperties": false
                },
                "description": "One entry for each UTC clock hour of the last 24 hours, oldest first. The last entry is the current hour so far."
              },
              "activityByDay": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": ["day", "ready", "failed"],
                  "properties": {
                    "day": {
                      "type": "string",
                      "description": "The UTC day, such as 2026-10-20."
                    },
                    "ready": {
                      "type": "number",
                      "description": "Live versions that became ready on this day."
                    },
                    "failed": {
                      "type": "number",
                      "description": "Live versions that failed on this day."
                    }
                  },
                  "additionalProperties": false
                },
                "description": "One entry for each UTC day of the last 30 days, oldest first. The last entry is today."
              },
              "lastReadyAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When the newest ready live version became ready, in UTC, or null."
              }
            },
            "additionalProperties": false
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObjectSummary"
            },
            "description": "One page of live versions that match the filter."
          },
          "nextCursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as cursor to read the next page, or null on the last page."
          }
        },
        "additionalProperties": false,
        "description": "The indexing status of a bucket: its counts and one page of its versions.",
        "title": "BucketIndexStatus"
      },
      "DeleteObjectResult": {
        "type": "object",
        "required": ["removedVersionId", "deleteMarkerVersionId", "cleanupPending"],
        "properties": {
          "removedVersionId": {
            "type": "string",
            "description": "The version that was removed."
          },
          "deleteMarkerVersionId": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The delete marker in a versioned bucket, or null."
          },
          "cleanupPending": {
            "type": "boolean",
            "description": "Provider cleanup is still running."
          }
        },
        "additionalProperties": false,
        "description": "What a delete removed.",
        "title": "DeleteObjectResult"
      },
      "RestoreObjectRequest": {
        "type": "object",
        "required": ["recoveryId"],
        "properties": {
          "recoveryId": {
            "type": "string",
            "description": "The recoveryId of a version in the recovery list of the bucket."
          }
        },
        "additionalProperties": false,
        "description": "The recovery copy to restore.",
        "title": "RestoreObjectRequest",
        "examples": [
          {
            "recoveryId": "ver_3f9c2a7d1e4b4c8a9f0d6b2e5a1c7d3f"
          }
        ]
      },
      "CopyObjectRequest": {
        "type": "object",
        "required": [],
        "properties": {
          "destinationKey": {
            "type": "string",
            "description": "The key to copy to, in the same bucket."
          }
        },
        "additionalProperties": false,
        "description": "Where to copy the object.",
        "title": "CopyObjectRequest",
        "examples": [
          {
            "destinationKey": "incidents/checkout-timeout-copy.json"
          }
        ]
      },
      "PresignRequest": {
        "anyOf": [
          {
            "type": "object",
            "required": ["operation", "key", "contentType", "lengthBytes"],
            "properties": {
              "operation": {
                "type": "string",
                "enum": ["PutObject"]
              },
              "key": {
                "type": "string",
                "description": "The object key."
              },
              "contentType": {
                "type": "string",
                "description": "The object content type."
              },
              "lengthBytes": {
                "type": "string",
                "description": "The body size in bytes, as a string of digits. It is signed.",
                "pattern": "^\\d{1,16}$"
              },
              "sha256": {
                "type": "string",
                "description": "The base64 SHA-256 of the body. Graphon Storage signs it and rejects other bytes.",
                "pattern": "^[A-Za-z0-9+/]{43}=$"
              },
              "metadata": {
                "type": "object",
                "required": [],
                "properties": {},
                "additionalProperties": {
                  "type": "string"
                },
                "description": "The metadata of the new object, by key. Graphon Storage signs each pair as an x-amz-meta-<key> header. A key is 1 to 128 lowercase letters, digits, periods, underscores, or hyphens. A value is printable ASCII, at most 1,024 bytes, and keys plus values take at most 2,048 bytes. A metadata field of the bucket can filter search on a key.",
                "examples": [
                  {
                    "team": "search",
                    "year": "2026"
                  }
                ]
              },
              "ifNoneMatch": {
                "type": "string",
                "enum": ["*"],
                "description": "Send * to create only. Graphon Storage rejects the PUT if the key exists."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "key"],
            "properties": {
              "operation": {
                "type": "string",
                "enum": ["GetObject"]
              },
              "key": {
                "type": "string",
                "description": "The object key."
              },
              "versionId": {
                "type": "string",
                "description": "The version to read."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "key", "contentType"],
            "properties": {
              "operation": {
                "type": "string",
                "enum": ["CreateMultipartUpload"]
              },
              "key": {
                "type": "string",
                "description": "The object key."
              },
              "contentType": {
                "type": "string",
                "description": "The object content type."
              },
              "metadata": {
                "type": "object",
                "required": [],
                "properties": {},
                "additionalProperties": {
                  "type": "string"
                },
                "description": "The metadata of the new object, by key. Graphon Storage signs each pair as an x-amz-meta-<key> header. A key is 1 to 128 lowercase letters, digits, periods, underscores, or hyphens. A value is printable ASCII, at most 1,024 bytes, and keys plus values take at most 2,048 bytes. A metadata field of the bucket can filter search on a key.",
                "examples": [
                  {
                    "team": "search",
                    "year": "2026"
                  }
                ]
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "key", "uploadId", "partNumber", "lengthBytes"],
            "properties": {
              "operation": {
                "type": "string",
                "enum": ["UploadPart"]
              },
              "key": {
                "type": "string",
                "description": "The object key."
              },
              "uploadId": {
                "type": "string",
                "description": "The multipart upload id."
              },
              "partNumber": {
                "type": "integer",
                "description": "The part number, from 1 to 10000.",
                "title": "between(1, 10000)",
                "minimum": 1,
                "maximum": 10000
              },
              "lengthBytes": {
                "type": "string",
                "description": "The body size in bytes, as a string of digits. It is signed.",
                "pattern": "^\\d{1,16}$"
              },
              "sha256": {
                "type": "string",
                "description": "The base64 SHA-256 of the body. Graphon Storage signs it and rejects other bytes.",
                "pattern": "^[A-Za-z0-9+/]{43}=$"
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "key", "uploadId"],
            "properties": {
              "operation": {
                "type": "string",
                "enum": ["CompleteMultipartUpload"]
              },
              "key": {
                "type": "string",
                "description": "The object key."
              },
              "uploadId": {
                "type": "string",
                "description": "The multipart upload id."
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": ["operation", "key", "uploadId"],
            "properties": {
              "operation": {
                "type": "string",
                "enum": ["AbortMultipartUpload"]
              },
              "key": {
                "type": "string",
                "description": "The object key."
              },
              "uploadId": {
                "type": "string",
                "description": "The multipart upload id."
              }
            },
            "additionalProperties": false
          }
        ],
        "description": "One S3 request to presign.",
        "title": "PresignRequest",
        "examples": [
          {
            "operation": "PutObject",
            "key": "incidents/checkout-timeout.json",
            "contentType": "application/json",
            "lengthBytes": "2048"
          }
        ]
      },
      "PresignResponse": {
        "type": "object",
        "required": ["method", "url", "headers", "expiresAt"],
        "properties": {
          "method": {
            "type": "string",
            "enum": ["PUT", "GET", "POST", "DELETE"],
            "description": "The HTTP method to send."
          },
          "url": {
            "type": "string",
            "description": "The presigned URL on the Graphon Storage host."
          },
          "headers": {
            "type": "object",
            "required": [],
            "properties": {},
            "additionalProperties": {
              "type": "string"
            },
            "description": "Send these headers exactly. Graphon Storage signs them."
          },
          "expiresAt": {
            "type": "string",
            "description": "When the URL stops working, in UTC."
          }
        },
        "additionalProperties": false,
        "description": "One presigned S3 request.",
        "title": "PresignResponse"
      },
      "BucketSummaryList": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BucketSummaryItem"
            }
          }
        },
        "additionalProperties": false,
        "description": "Every bucket in the workspace, with its usage and indexing counts.",
        "title": "BucketSummaryList"
      },
      "BucketSummaryItem": {
        "type": "object",
        "required": ["bucket", "usage", "index", "error"],
        "properties": {
          "bucket": {
            "$ref": "#/components/schemas/Bucket"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Usage"
              },
              {
                "type": "null"
              }
            ],
            "description": "The storage that the bucket uses, or null when the bucket is not active."
          },
          "index": {
            "anyOf": [
              {
                "type": "object",
                "required": [
                  "status",
                  "counts",
                  "olderVersionSearchable",
                  "oldestUnfinishedSince",
                  "activityByHour",
                  "activityByDay",
                  "lastReadyAt"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": ["empty", "indexing", "ready", "degraded", "failed"],
                    "description": "empty: no live object. indexing: something unfinished and nothing ready. ready: something ready and nothing failed. degraded: something ready and something failed. failed: objects exist and none is ready."
                  },
                  "counts": {
                    "type": "object",
                    "required": [
                      "preparing",
                      "sending",
                      "queued",
                      "indexing",
                      "ready",
                      "failed",
                      "unsupported"
                    ],
                    "properties": {
                      "preparing": {
                        "type": "number",
                        "description": "Live versions that are preparing."
                      },
                      "sending": {
                        "type": "number",
                        "description": "Live versions that are sending."
                      },
                      "queued": {
                        "type": "number",
                        "description": "Live versions that are queued."
                      },
                      "indexing": {
                        "type": "number",
                        "description": "Live versions that are indexing."
                      },
                      "ready": {
                        "type": "number",
                        "description": "Live versions that are ready."
                      },
                      "failed": {
                        "type": "number",
                        "description": "Live versions that are failed."
                      },
                      "unsupported": {
                        "type": "number",
                        "description": "Live versions that are unsupported."
                      }
                    },
                    "additionalProperties": false
                  },
                  "olderVersionSearchable": {
                    "type": "number",
                    "description": "Live keys whose search still returns an older version."
                  },
                  "oldestUnfinishedSince": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "When the longest-waiting unfinished version started its state, in UTC, or null."
                  },
                  "activityByHour": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["hour", "ready", "failed"],
                      "properties": {
                        "hour": {
                          "type": "string",
                          "description": "The start of the UTC hour, such as 2026-10-20T14:00:00.000Z."
                        },
                        "ready": {
                          "type": "number",
                          "description": "Live versions that became ready in this hour."
                        },
                        "failed": {
                          "type": "number",
                          "description": "Live versions that failed in this hour."
                        }
                      },
                      "additionalProperties": false
                    },
                    "description": "One entry for each UTC clock hour of the last 24 hours, oldest first. The last entry is the current hour so far."
                  },
                  "activityByDay": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["day", "ready", "failed"],
                      "properties": {
                        "day": {
                          "type": "string",
                          "description": "The UTC day, such as 2026-10-20."
                        },
                        "ready": {
                          "type": "number",
                          "description": "Live versions that became ready on this day."
                        },
                        "failed": {
                          "type": "number",
                          "description": "Live versions that failed on this day."
                        }
                      },
                      "additionalProperties": false
                    },
                    "description": "One entry for each UTC day of the last 30 days, oldest first. The last entry is today."
                  },
                  "lastReadyAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "When the newest ready live version became ready, in UTC, or null."
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "The indexing counts, or null when indexing is disabled or the bucket is not active."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The error code when the bucket could not be read, or null."
          }
        },
        "additionalProperties": false,
        "description": "One bucket with its usage and indexing counts.",
        "title": "BucketSummaryItem"
      },
      "RecoveryList": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["recoveryId", "key", "versionId", "expiresAt", "sizeBytes"],
              "properties": {
                "recoveryId": {
                  "type": "string",
                  "description": "Pass to POST …/restore."
                },
                "key": {
                  "type": "string",
                  "description": "The object key."
                },
                "versionId": {
                  "type": "string",
                  "description": "The version id."
                },
                "expiresAt": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "When recovery ends, in UTC, or null when it has no end."
                },
                "sizeBytes": {
                  "type": "string",
                  "description": "The size in bytes."
                }
              },
              "additionalProperties": false
            },
            "description": "Deleted or replaced versions that can be restored."
          }
        },
        "additionalProperties": false,
        "description": "Recovery copies in one bucket.",
        "title": "RecoveryList"
      },
      "ActivityList": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["id", "kind", "outcome", "at", "detail"],
              "properties": {
                "id": {
                  "type": "string",
                  "description": "The activity id."
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "object.deleted",
                    "object.restored",
                    "bucket.renamed",
                    "bucket.access_changed",
                    "bucket.availability_changed",
                    "bucket.recovery_changed",
                    "bucket.emptied",
                    "bucket.provisioning_retried"
                  ],
                  "description": "What happened: an object deleted or restored, or a bucket renamed, its access, availability, or recovery period changed, emptied, or provisioning retried."
                },
                "outcome": {
                  "type": "string",
                  "enum": ["succeeded"],
                  "description": "Always succeeded."
                },
                "at": {
                  "type": "string",
                  "description": "When it happened, in UTC."
                },
                "detail": {
                  "$id": "/schemas/unknown",
                  "description": "Details for the kind, such as the key, the old and new names, or the new setting.",
                  "title": "unknown"
                }
              },
              "additionalProperties": false
            },
            "description": "The newest activity first."
          }
        },
        "additionalProperties": false,
        "description": "Recent changes to one bucket made through the JSON API, the app, the CLI, or MCP. S3-protocol writes and deletes are not recorded.",
        "title": "ActivityList"
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "description": "Send Authorization: Bearer with an API key (gak_…) or a temporary key (gtk_…). A key acts only in its own workspace, at its role: viewer, editor, or admin.",
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "Buckets",
      "description": "Buckets and their settings."
    },
    {
      "name": "Objects",
      "description": "Objects, their versions, and presigned S3 requests."
    },
    {
      "name": "Insights",
      "description": "Usage, activity, metrics, and recovery for a bucket."
    }
  ],
  "servers": [
    {
      "url": "https://storage.beta.graphon.sh"
    }
  ]
}
