> ## Documentation Index
> Fetch the complete documentation index at: https://docs.r2vault.app/llms.txt
> Use this file to discover all available pages before exploring further.

# R2Credentials

> Storage credentials and configuration for Cloudflare R2

## Overview

The `R2Credentials` struct stores authentication credentials and configuration for connecting to a Cloudflare R2 bucket. It provides computed properties for endpoint URLs and methods for generating public URLs for uploaded objects.

## Properties

<ResponseField name="id" type="UUID" required>
  Unique identifier for this credential set
</ResponseField>

<ResponseField name="accountId" type="String" required>
  Cloudflare account ID used to construct the R2 endpoint URL
</ResponseField>

<ResponseField name="accessKeyId" type="String" required>
  R2 access key ID for S3-compatible authentication
</ResponseField>

<ResponseField name="secretAccessKey" type="String" required>
  R2 secret access key for S3-compatible authentication
</ResponseField>

<ResponseField name="bucketName" type="String" required>
  Name of the R2 bucket to use for storage operations
</ResponseField>

<ResponseField name="customDomain" type="String?">
  Optional custom domain for public URLs. If provided, public URLs will use this domain instead of the default R2 endpoint
</ResponseField>

<ResponseField name="isEmpty" type="Bool" computed>
  Returns `true` if any required credential fields are empty
</ResponseField>

<ResponseField name="endpoint" type="URL" computed>
  The S3-compatible endpoint URL for this R2 account, formatted as:

  ```text theme={null}
  https://{accountId}.r2.cloudflarestorage.com
  ```
</ResponseField>

## Methods

### publicURL(forKey:)

Constructs the public URL for an uploaded object.

<ResponseField name="key" type="String" required>
  The object key (path) in the R2 bucket
</ResponseField>

**Returns:** `URL` - The public URL for accessing the object

**Behavior:**

* If `customDomain` is set, returns `{customDomain}/{key}`
* Otherwise, returns `{endpoint}/{bucketName}/{key}`

## Source Code

```swift R2Credentials.swift theme={null}
import Foundation

struct R2Credentials: Sendable, Codable, Equatable, Identifiable {
    var id: UUID
    var accountId: String
    var accessKeyId: String
    var secretAccessKey: String
    var bucketName: String
    var customDomain: String?

    var isEmpty: Bool {
        accountId.isEmpty || accessKeyId.isEmpty || secretAccessKey.isEmpty || bucketName.isEmpty
    }

    init(
        id: UUID = UUID(),
        accountId: String,
        accessKeyId: String,
        secretAccessKey: String,
        bucketName: String,
        customDomain: String? = nil
    ) {
        self.id = id
        self.accountId = accountId
        self.accessKeyId = accessKeyId
        self.secretAccessKey = secretAccessKey
        self.bucketName = bucketName
        self.customDomain = customDomain
    }

    /// S3-compatible endpoint for this R2 account
    var endpoint: URL {
        URL(string: "https://\(accountId).r2.cloudflarestorage.com")!
    }

    /// Constructs the public URL for an uploaded object key
    func publicURL(forKey key: String) -> URL {
        if let customDomain, !customDomain.isEmpty,
           let base = URL(string: customDomain) {
            return base.appendingPathComponent(key)
        }
        return endpoint
            .appendingPathComponent(bucketName)
            .appendingPathComponent(key)
    }
}
```

## Protocols

* `Sendable` - Thread-safe value type
* `Codable` - Can be encoded/decoded to/from JSON or other formats
* `Equatable` - Can be compared for equality
* `Identifiable` - Has a unique `id` property

## Usage Example

```swift theme={null}
let credentials = R2Credentials(
    accountId: "abc123",
    accessKeyId: "your-access-key",
    secretAccessKey: "your-secret-key",
    bucketName: "my-bucket",
    customDomain: "https://cdn.example.com"
)

// Get the S3 endpoint
let endpoint = credentials.endpoint
// https://abc123.r2.cloudflarestorage.com

// Generate a public URL
let publicURL = credentials.publicURL(forKey: "images/photo.jpg")
// https://cdn.example.com/images/photo.jpg
```
