Supabase.Storage
8.0.0
dotnet add package Supabase.Storage --version 8.0.0
NuGet\Install-Package Supabase.Storage -Version 8.0.0
<PackageReference Include="Supabase.Storage" Version="8.0.0" />
<PackageVersion Include="Supabase.Storage" Version="8.0.0" />
<PackageReference Include="Supabase.Storage" />
paket add Supabase.Storage --version 8.0.0
#r "nuget: Supabase.Storage, 8.0.0"
#:package Supabase.Storage@8.0.0
#addin nuget:?package=Supabase.Storage&version=8.0.0
#tool nuget:?package=Supabase.Storage&version=8.0.0
Supabase.Storage
A C# client for Supabase Storage — upload, download, and serve files from buckets, with signed and public URLs.
Part of the Supabase C# SDK. Most projects
use it through the Supabase meta-package (supabase.Storage); reference
this package directly when you only need storage.
Installation
dotnet add package Supabase.Storage
Targets .NET Standard 2.0.
Getting started
Create a client pointed at your project's Storage URL, passing your key as a header:
using Supabase.Storage;
var client = new Client("https://PROJECT_ID.supabase.co/storage/v1", new Dictionary<string, string>
{
{ "apikey", SUPABASE_KEY },
{ "Authorization", $"Bearer {SUPABASE_KEY}" }
});
Buckets
await client.CreateBucket("avatars");
var bucket = await client.GetBucket("avatars");
var all = await client.ListBuckets();
await client.EmptyBucket("avatars");
await client.DeleteBucket("avatars");
Files
Work with a bucket's files through From:
var bucket = client.From("avatars");
// Upload from a local path or from bytes.
await bucket.Upload("./local.png", "me.png");
await bucket.Upload(bytes, "me.png");
// List, move, copy, remove.
var files = await bucket.List();
await bucket.Move("me.png", "old/me.png");
await bucket.Copy("old/me.png", "backup/me.png");
await bucket.Remove("old/me.png");
// Download to a local path (returns the path) or into memory (returns bytes).
await bucket.Download("me.png", "./downloaded.png");
byte[] data = await bucket.Download("me.png");
URLs
// Public bucket: build a URL directly (pass null for no image transform).
var publicUrl = bucket.GetPublicUrl("me.png", null);
// Private bucket: sign a URL that expires (seconds).
var signedUrl = await bucket.CreateSignedUrl("me.png", 3600);
Error handling
Storage failures throw a SupabaseStorageException. Use Code for the exact service error (for
example, NoSuchKey) and Reason for the broader classification. Code is null when the response
does not include one. See the Storage error code reference.
Observability (OpenTelemetry)
The client emits traces and metrics through System.Diagnostics, so you can wire them into
OpenTelemetry (or any ActivityListener / MeterListener) without taking a dependency on the
OpenTelemetry packages. Emission is zero-cost while nothing is listening, so it is always on and stays
silent until you subscribe.
Register the client's ActivitySource and Meter by name. Use the StorageDiagnostics.SourceName
constant rather than hardcoding the string, so a typo becomes a compile error instead of a silent
no-op:
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
using Supabase.Storage;
// Requires OpenTelemetry.Extensions.Hosting and an exporter package (e.g. OTLP) in your app.
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource(StorageDiagnostics.SourceName)
.AddOtlpExporter())
.WithMetrics(metrics => metrics
.AddMeter(StorageDiagnostics.SourceName)
.AddOtlpExporter());
Once subscribed you get:
- A client span per request, named
{METHOD} {path}and following OpenTelemetry HTTP conventions (method, status code, and a sanitized URL). The query string is never recorded — Storage signed URLs carry atokenthere. Upload and download spans additionally carry astorage.transfer.directiontag (upload/download). The resumable (TUS) upload is reported as a single operation span covering the whole transfer, rather than one span per underlying chunk request. supabase.storage.http.request.duration(seconds) for control-plane requests.supabase.storage.transfer.duration(seconds) andsupabase.storage.transfer.size(bytes) for uploads and downloads, tagged by direction — because a duration alone does not describe a file transfer.
If you are not using the OpenTelemetry SDK, a raw listener works too:
using System.Diagnostics;
using Supabase.Storage;
using var listener = new ActivityListener
{
ShouldListenTo = source => source.Name == StorageDiagnostics.SourceName,
Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllData,
ActivityStopped = activity => Console.WriteLine($"{activity.OperationName} {activity.Duration.TotalMilliseconds}ms {activity.Status}")
};
ActivitySource.AddActivityListener(listener);
Contributing
Contributions are welcome. See the repository root for how to build and test the SDK.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- BirdMessenger (>= 4.0.0)
- MimeMapping (>= 4.0.0)
- Supabase.Core (>= 8.0.0)
- System.Diagnostics.DiagnosticSource (>= 8.0.1)
- System.Text.Json (>= 8.0.5)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Supabase.Storage:
| Package | Downloads |
|---|---|
|
Supabase
A C# implementation of the Supabase client |
|
|
benxu.AppPlatform.Supabase.Storage
Supabase Storage implementation for benxu App Platform. Provides object upload, download, listing, file copy, move, delete, and signed/public URL generation for .NET MAUI applications. |
GitHub repositories
This package is not used by any popular GitHub repositories.