openapi: 3.0.0 info: title: S5 Storage API version: "1.0" paths: # Account API /s5/account/register: get: summary: Initiate account registration tags: - account security: [] parameters: - name: pubKey description: Public key of the account in: query required: true schema: type: string responses: '200': description: Registration challenge post: summary: Complete account registration tags: - account security: [] requestBody: content: application/json: schema: $ref: '#/components/schemas/AccountRegisterRequest' responses: '201': description: Account created /s5/account/login: get: summary: Initiate account login tags: - account security: [] parameters: - name: pubKey description: Public key of the account in: query required: true schema: type: string responses: '200': description: Login challenge post: summary: Complete account login tags: - account security: [] requestBody: content: application/json: schema: $ref: '#/components/schemas/AccountLoginRequest' responses: '200': description: Login successful /s5/account: get: summary: Retrieve account information tags: - account responses: '200': description: Account information /s5/account/stats: get: summary: Retrieve account statistics tags: - account responses: '200': description: Account statistics content: application/json: schema: $ref: "#/components/schemas/AccountStatsResponse" /s5/account/pins: get: summary: Retrieve account pins tags: - account responses: '200': description: Account pins content: application/json: schema: $ref: '#/components/schemas/AccountPinsResponse' '401': description: Unauthorized /s5/account/pins.bin: get: summary: Retrieve account pins tags: - account responses: '200': description: Account pins '401': description: Unauthorized # Upload API /s5/upload: post: summary: Upload a small file tags: - upload requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary application/octet-stream: schema: type: string format: binary responses: '200': description: File uploaded content: application/json: schema: $ref: '#/components/schemas/BasicUploadResponse' '500': description: Error uploading file /s5/upload/directory: post: summary: Upload a directory tags: - upload description: > This endpoint accepts multiple files in a multipart/form-data request. Each file can be uploaded under its own field name, which the server will process dynamically. The endpoint also accepts additional query parameters such as `tryfiles` and `errorpages` to configure the upload behavior. parameters: - name: tryFiles in: query required: true schema: $ref: '#/components/schemas/UploadRequestTryFiles' - name: errorPages in: query required: true schema: $ref: '#/components/schemas/UploadRequestErrorPages' - name: name in: query required: true schema: type: string requestBody: content: multipart/form-data: schema: type: object additionalProperties: type: string format: binary responses: '201': description: Directory uploaded content: application/json: schema: $ref: '#/components/schemas/BasicUploadResponse' # Tus API /s5/upload/tus: post: summary: TUS Upload tags: - upload - tus description: > An empty POST request is used to create a new upload resource. The Upload-Length header indicates the size of the entire upload in bytes. If the Creation With Upload extension is available, the Client MAY include parts of the upload in the initial Creation request parameters: - name: Content-Length in: header description: Must be 0 for creation extension. May be a positive number for Creation With Upload extension. schema: type: integer - name: Upload-Length in: header schema: $ref: "#/components/schemas/Upload-Length" - name: Tus-Resumable in: header schema: $ref: "#/components/schemas/Tus-Resumable" - name: Upload-Metadata in: header description: Added by the Creation extension. The Upload-Metadata request and response header MUST consist of one or more comma-separated key-value pairs. The key and value MUST be separated by a space. The key MUST NOT contain spaces and commas and MUST NOT be empty. The key SHOULD be ASCII encoded and the value MUST be Base64 encoded. All keys MUST be unique. The value MAY be empty. In these cases, the space, which would normally separate the key and the value, MAY be left out. Since metadata can contain arbitrary binary values, Servers SHOULD carefully validate metadata values or sanitize them before using them as header values to avoid header smuggling. schema: type: string - name: Upload-Concat in: header description: Added by the Concatenation extension. The Upload-Concat request and response header MUST be set in both partial and final upload creation requests. It indicates whether the upload is either a partial or final upload. If the upload is a partial one, the header value MUST be partial. In the case of a final upload, its value MUST be final followed by a semicolon and a space-separated list of partial upload URLs that will be concatenated. The partial uploads URLs MAY be absolute or relative and MUST NOT contain spaces as defined in RFC 3986. schema: type: string - name: Upload-Defer-Length in: header description: Added by the Creation Defer Length extension. The Upload-Defer-Length request and response header indicates that the size of the upload is not known currently and will be transferred later. Its value MUST be 1. If the length of an upload is not deferred, this header MUST be omitted. schema: type: integer enum: - 1 - name: Upload-Offset in: header schema: $ref: "#/components/schemas/Upload-Offset" - name: Upload-Checksum in: header schema: $ref: "#/components/schemas/Upload-Checksum" requestBody: description: (Possibly partial) content of the file. Required if Content-Length > 0. required: false content: application/offset+octet-stream: schema: type: string format: binary responses: 201: description: Created headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Upload-Offset: schema: $ref: "#/components/schemas/Upload-Offset" Upload-Expires: description: Added by the Creation With Upload Extension in combination with the expiration extension. The Upload-Expires response header indicates the time after which the unfinished upload expires. A Server MAY wish to remove incomplete uploads after a given period of time to prevent abandoned uploads from taking up extra storage. The Client SHOULD use this header to determine if an upload is still valid before attempting to resume the upload. This header MUST be included in every PATCH response if the upload is going to expire. If the expiration is known at the creation, the Upload-Expires header MUST be included in the response to the initial POST request. Its value MAY change over time. If a Client does attempt to resume an upload which has since been removed by the Server, the Server SHOULD respond with the 404 Not Found or 410 Gone status. The latter one SHOULD be used if the Server is keeping track of expired uploads. In both cases the Client SHOULD start a new upload. The value of the Upload-Expires header MUST be in RFC 7231 datetime format. schema: type: string Location: description: Url of the created resource. schema: type: string 400: description: Added by the Creation With Upload Extension in combination with the checksum extension. The checksum algorithm is not supported by the server headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 412: description: Precondition Failed headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Tus-Version: schema: $ref: "#/components/schemas/Tus-Version" 413: description: If the length of the upload exceeds the maximum, which MAY be specified using the Tus-Max-Size header, the Server MUST respond with the 413 Request Entity Too Large status. headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 415: description: Added by the Creation With Upload Extension. Content-Type was not application/offset+octet-stream headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 460: description: Added by the Creation With Upload Extension in combination with the checksum extension. Checksums mismatch headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" options: summary: Request to gather information about the Server's current configuration description: An OPTIONS request MAY be used to gather information about the Server's current configuration. A successful response indicated by the 204 No Content or 200 OK status MUST contain the Tus-Version header. It MAY include the Tus-Extension and Tus-Max-Size headers. responses: 200: description: Success headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Tus-Checksum-Algorithm: schema: $ref: "#/components/schemas/Tus-Checksum-Algorithm" Tus-Version: schema: $ref: "#/components/schemas/Tus-Version" Tus-Max-Size: schema: $ref: "#/components/schemas/Tus-Max-Size" Tus-Extension: schema: $ref: "#/components/schemas/Tus-Extension" 204: description: Success headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Tus-Checksum-Algorithm: schema: $ref: "#/components/schemas/Tus-Checksum-Algorithm" Tus-Version: schema: $ref: "#/components/schemas/Tus-Version" Tus-Max-Size: schema: $ref: "#/components/schemas/Tus-Max-Size" Tus-Extension: schema: $ref: "#/components/schemas/Tus-Extension" /s5/upload/tus/{id}: delete: summary: Added by the Termination extension. tags: - upload - tus description: When receiving a DELETE request for an existing upload the Server SHOULD free associated resources and MUST respond with the 204 No Content status confirming that the upload was terminated. For all future requests to this URL, the Server SHOULD respond with the 404 Not Found or 410 Gone status. operationId: FilesDelete parameters: - name: id in: path required: true schema: type: string - name: Tus-Resumable in: header required: true schema: $ref: "#/components/schemas/Tus-Resumable" responses: 204: description: Upload was terminated headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 412: description: Precondition Failed headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Tus-Version: schema: $ref: "#/components/schemas/Tus-Version" head: summary: Used to determine the offset at which the upload should be continued. tags: - upload - tus description: Used to determine the offset at which the upload should be continued. operationId: FilesHead parameters: - name: id in: path required: true schema: type: string - name: Tus-Resumable in: header required: true schema: $ref: "#/components/schemas/Tus-Resumable" responses: 200: description: Returns offset headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Cache-Control: schema: type: string enum: - no-store Upload-Offset: schema: $ref: "#/components/schemas/Upload-Offset" Upload-Length: schema: $ref: "#/components/schemas/Upload-Length" 403: description: If the resource is not found, the Server SHOULD return either the 404 Not Found, 410 Gone or 403 Forbidden status without the Upload-Offset header. headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 404: description: If the resource is not found, the Server SHOULD return either the 404 Not Found, 410 Gone or 403 Forbidden status without the Upload-Offset header. headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 410: description: If the resource is not found, the Server SHOULD return either the 404 Not Found, 410 Gone or 403 Forbidden status without the Upload-Offset header. headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 412: description: Precondition Failed headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Tus-Version: schema: $ref: "#/components/schemas/Tus-Version" patch: summary: Used to resume the upload tags: - upload - tus description: 'The Server SHOULD accept PATCH requests against any upload URL and apply the bytes contained in the message at the given offset specified by the Upload-Offset header. All PATCH requests MUST use Content-Type: application/offset+octet-stream, otherwise the server SHOULD return a 415 Unsupported Media Type status.' operationId: FilePatch parameters: - name: id in: path required: true schema: type: string - name: Tus-Resumable in: header required: true schema: $ref: "#/components/schemas/Tus-Resumable" - name: Content-Length in: header description: Length of the body of this request required: true schema: type: integer - name: Upload-Offset in: header required: true schema: $ref: "#/components/schemas/Upload-Offset" - name: Upload-Checksum in: header schema: $ref: "#/components/schemas/Upload-Checksum" requestBody: description: Remaining (possibly partial) content of the file. Required if Content-Length > 0. required: false content: application/offset+octet-stream: schema: type: string format: binary responses: 204: description: Upload offset was updated headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Upload-Offset: schema: $ref: "#/components/schemas/Tus-Resumable" Upload-Expires: description: Added by the expiration extension. The Upload-Expires response header indicates the time after which the unfinished upload expires. A Server MAY wish to remove incomplete uploads after a given period of time to prevent abandoned uploads from taking up extra storage. The Client SHOULD use this header to determine if an upload is still valid before attempting to resume the upload. This header MUST be included in every PATCH response if the upload is going to expire. If the expiration is known at the creation, the Upload-Expires header MUST be included in the response to the initial POST request. Its value MAY change over time. If a Client does attempt to resume an upload which has since been removed by the Server, the Server SHOULD respond with the 404 Not Found or 410 Gone status. The latter one SHOULD be used if the Server is keeping track of expired uploads. In both cases the Client SHOULD start a new upload. The value of the Upload-Expires header MUST be in RFC 7231 datetime format. schema: type: string 400: description: Added by the checksum extension. The checksum algorithm is not supported by the server headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 403: description: In the concatenation extension, the Server MUST respond with the 403 Forbidden status to PATCH requests against a final upload URL and MUST NOT modify the final or its partial uploads. headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 404: description: PATCH request against a non-existent resource headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 409: description: PATCH request with Upload-Offset unequal to the offset of the resource on the server. The Upload-Offset header's value MUST be equal to the current offset of the resource. headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 410: description: PATCH request against a non-existent resource headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 412: description: Precondition Failed headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" Tus-Version: schema: $ref: "#/components/schemas/Tus-Version" 415: description: Content-Type was not application/offset+octet-stream headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" 460: description: Added by the checksum extension. Checksums mismatch headers: Tus-Resumable: schema: $ref: "#/components/schemas/Tus-Resumable" # Download API /s5/blob/{cid}: get: summary: Retrieve a blob tags: - download parameters: - name: cid in: path required: true schema: type: string responses: '302': description: Redirecting to discovered blob url /s5/metadata/{cid}: get: summary: Retrieve file metadata tags: - download parameters: - name: cid in: path required: true schema: type: string description: > * Resolvers are currently not supported * Raw files don't have metadata responses: '200': description: File metadata content: application/json: schema: type: object '415': description: Unsupported content type /s5/download/{cid}: get: summary: Download a file tags: - download parameters: - name: cid in: path required: true schema: type: string responses: '200': description: File content content: application/octet-stream: schema: type: string format: binary # Pins API /s5/pin/{cid}: post: summary: Pin a file tags: - pin parameters: - name: cid in: path required: true schema: type: string responses: '204': description: File pinned /s5/pin/{cid}/status: get: summary: Retrieve pin status tags: - pin parameters: - name: cid in: path required: true schema: type: string responses: '200': description: Pin status content: application/json: schema: $ref: '#/components/schemas/AccountPinStatusResponse' /s5/delete/{cid}: delete: summary: Delete a file. This will only unpin it from the account, and potentially delete it later if there are no more global pins. tags: - pin parameters: - name: cid in: path required: true schema: type: string responses: '200': description: File deleted # Debug API /s5/debug/download_urls/{cid}: get: summary: Retrieve download URLs tags: - debug parameters: - name: cid in: path required: true schema: type: string - name: hash in: query required: true schema: type: string description: This is base64 url encoded - name: kinds in: query required: false schema: type: string description: This is a comma separated list of kinds, which are integer identifiers. responses: '200': description: Download URLs content: text/plain: schema: type: string /s5/debug/storage_locations/{hash}: get: summary: Retrieve storage locations tags: - debug parameters: - name: hash in: path required: true schema: type: string description: This is base64 url encoded responses: '200': description: Storage locations content: application/json: schema: $ref: '#/components/schemas/DebugStorageLocationsResponse' # Registry API /s5/registry: get: summary: Retrieve a registry entry tags: - registry parameters: - name: pk description: Public key of the registry entry in: query required: true schema: type: string responses: '200': description: Registry entry content: application/json: schema: $ref: '#/components/schemas/RegistryQueryResponse' post: summary: Create or update a registry entry tags: - registry requestBody: content: application/json: schema: $ref: '#/components/schemas/RegistrySetRequest' responses: '200': description: Registry entry set /s5/registry/subscription: post: summary: Listen for websocket updates for a given registry entry tags: - registry requestBody: content: text/plain: schema: nullable: true responses: '200': description: Success components: schemas: AccountRegisterChallengeResponse: type: object properties: challenge: type: string AccountRegisterRequest: type: object properties: pubkey: type: string description: This is base64 url encoded response: type: string description: This is base64 url encoded signature: type: string description: This is base64 url encoded email: type: string required: - pubkey - response - signature AccountLoginChallengeResponse: type: object properties: challenge: type: string description: This is base64 url encoded AccountLoginRequest: type: object properties: pubkey: type: string description: This is base64 url encoded response: type: string description: This is base64 url encoded signature: type: string description: This is base64 url encoded required: - pubkey - response - signature BasicUploadResponse: type: object properties: cid: type: string UploadRequestTryFiles: type: array items: type: string UploadRequestErrorPages: type: object additionalProperties: type: string description: > Object keys are expected to be string representations of integers (e.g., "404", "500"), with their values being strings. Due to limitations in the OpenAPI Specification, this pattern cannot be enforced through the schema and should be validated at runtime. AccountStats: type: object properties: total: $ref: '#/components/schemas/AccountStatsTotal' AccountStatsTotal: type: object properties: usedStorage: type: integer AccountTier: type: object properties: id: type: integer name: type: string uploadBandwidth: type: integer storageLimit: type: integer scopes: type: array items: type: object AccountInfoResponse: type: object properties: email: type: string quotaExceeded: type: boolean emailConfirmed: type: boolean isRestricted: type: boolean tier: $ref: '#/components/schemas/AccountTier' AccountStatsResponse: allOf: - $ref: "#/components/schemas/AccountInfoResponse" - type: object properties: stats: $ref: "#/components/schemas/AccountStats" AccountPinsResponse: type: object required: - pins properties: pins: type: array items: $ref: '#/components/schemas/AccountPin' AccountPin: type: object required: - hash - size - pinned_at - mime_type properties: hash: type: string size: type: integer pinned_at: type: string mime_type: type: string AccountPinStatusResponse: type: object required: - status - progress properties: status: type: string progress: type: number RegistryQueryResponse: type: object properties: pk: type: string revision: type: integer data: type: string signature: type: string RegistrySetRequest: type: object properties: pk: type: string revision: type: integer data: type: string signature: type: string DebugStorageLocationsResponse: type: object properties: locations: type: array items: $ref: '#/components/schemas/DebugStorageLocation' DebugStorageLocation: type: object properties: location: type: integer parts: type: array items: type: string expiry: type: integer nodeId: type: string score: type: integer Tus-Resumable: type: string enum: - 1.0.0 description: Protocol version Tus-Version: description: The Tus-Version response header MUST be a comma-separated list of protocol versions supported by the Server. The list MUST be sorted by Server's preference where the first one is the most preferred one. type: string Tus-Extension: description: The Tus-Extension response header MUST be a comma-separated list of the extensions supported by the Server. If no extensions are supported, the Tus-Extension header MUST be omitted. type: string Tus-Max-Size: description: The Tus-Max-Size response header MUST be a non-negative integer indicating the maximum allowed size of an entire upload in bytes. The Server SHOULD set this header if there is a known hard limit. type: integer Upload-Length: description: The Upload-Length request and response header indicates the size of the entire upload in bytes. The value MUST be a non-negative integer. In the concatenation extension, the Client MUST NOT include the Upload-Length header in the final upload creation type: integer Upload-Offset: description: The Upload-Offset request and response header indicates a byte offset within a resource. The value MUST be a non-negative integer. type: integer Tus-Checksum-Algorithm: description: Added by the checksum extension. The Tus-Checksum-Algorithm response header MUST be a comma-separated list of the checksum algorithms supported by the server. type: string Upload-Checksum: description: Added by the checksum extension. The Upload-Checksum request header contains information about the checksum of the current body payload. The header MUST consist of the name of the used checksum algorithm and the Base64 encoded checksum separated by a space. type: string securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT CookieAuth: type: apiKey in: cookie name: s5-auth-token QueryAuth: type: apiKey in: query name: s5-auth-token security: - BearerAuth: [] - CookieAuth: [] - QueryAuth: [] tags: - name: account description: Account API - name: upload description: Upload API - name: tus description: TUS API - name: download description: Download API - name: pin description: Pins API - name: debug description: Debug API - name: registry description: Registry API