# Files

## Upload file bytes directly

`client.Files.New(ctx, params) (*SGPFile, error)`

**post** `/v5/files`

Upload a file's bytes directly and create a file record.

Send the file as multipart/form-data in the `file` field; the request body
carries the raw bytes, unlike cloud_imports which only references blobs that
already exist in cloud storage. The upload is rejected if it exceeds 25 MB;
larger or direct-to-storage uploads use a separate upload flow. The server
detects the content type from the bytes and rejects content that fails the
structural validation for that type. Content is deduplicated by checksum
and MIME type, so uploading bytes identical to an existing file reuses the
already-stored object instead of storing a second copy. Returns the created
file's metadata.

### Parameters

- `params FileNewParams`

  - `File param.Field[Reader]`

    Body param

  - `XProjectID param.Field[string]`

    Header param

### Returns

- `type SGPFile struct{…}`

  - `ID string`

    The unique identifier of the entity.

  - `CreatedAt Time`

    The date and time when the entity was created in ISO format.

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Filename string`

  - `Md5Checksum string`

  - `MimeType string`

  - `Size int64`

  - `DurationSeconds int64`

  - `Object SGPFileObject`

    - `const SGPFileObjectFile SGPFileObject = "file"`

  - `Tags map[string, any]`

### Example

```go
package main

import (
  "bytes"
  "context"
  "fmt"
  "io"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  sgpFile, err := client.Files.New(context.TODO(), sgpdev.FileNewParams{
    File: io.Reader(bytes.NewBuffer([]byte("Example data"))),
  })
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", sgpFile.ID)
}
```

#### Response

```json
{
  "id": "id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "filename": "filename",
  "md5_checksum": "md5_checksum",
  "mime_type": "mime_type",
  "size": 0,
  "duration_seconds": 0,
  "object": "file",
  "tags": {
    "foo": "bar"
  }
}
```

## Import files from cloud storage

`client.Files.ImportFromCloud(ctx, params) (*FileImportFromCloudResponse, error)`

**post** `/v5/files/cloud_imports`

Register files that already exist in cloud blob storage as file records, in one batch.

Unlike upload, this transfers no bytes: each entry references an existing
object by its container/bucket, filepath, filename, and MIME type, and only a
metadata record pointing at that object is created. Files are imported
independently and the response reports a per-file status. The response is 200
when every import succeeds and 207 when results are mixed, with each result
marked SUCCESS or a failure reason (file does not exist, invalid permissions,
or unknown error). Failed entries carry only the submitted filename and MIME
type rather than a full file record.

### Parameters

- `params FileImportFromCloudParams`

  - `Files param.Field[[]FileImportFromCloudParamsFile]`

    Body param: List of files to import from cloud storage

    - `Container string`

      The cloud storage container/bucket name

    - `FileType string`

      The MIME type of the file

    - `Filename string`

      The name of the file

    - `Filepath string`

      The path to the file within the container

  - `XProjectID param.Field[string]`

    Header param

### Returns

- `type FileImportFromCloudResponse struct{…}`

  - `Results []FileImportFromCloudResponseResult`

    Results for each file import attempt

    - `File FileImportFromCloudResponseResultFileUnion`

      The file object (full File for success, minimal _FailedFile for failures)

      - `type SGPFile struct{…}`

        - `ID string`

          The unique identifier of the entity.

        - `CreatedAt Time`

          The date and time when the entity was created in ISO format.

        - `CreatedBy Identity`

          The identity that created the entity.

          - `ID string`

          - `Type IdentityType`

            - `const IdentityTypeUser IdentityType = "user"`

            - `const IdentityTypeServiceAccount IdentityType = "service_account"`

          - `Object IdentityObject`

            - `const IdentityObjectIdentity IdentityObject = "identity"`

        - `Filename string`

        - `Md5Checksum string`

        - `MimeType string`

        - `Size int64`

        - `DurationSeconds int64`

        - `Object SGPFileObject`

          - `const SGPFileObjectFile SGPFileObject = "file"`

        - `Tags map[string, any]`

      - `type FileImportFromCloudResponseResultFile_FailedFile struct{…}`

        Minimal file representation for failed uploads containing only essential information.

        - `Filename string`

          The original filename from the request

        - `MimeType string`

          The original MIME type from the request

        - `Object string`

          - `const FileImportFromCloudResponseResultFile_FailedFileObjectFailedFile FileImportFromCloudResponseResultFile_FailedFileObject = "failed_file"`

    - `Status string`

      The status of the upload attempt

      - `const FileImportFromCloudResponseResultStatusSuccess FileImportFromCloudResponseResultStatus = "SUCCESS"`

      - `const FileImportFromCloudResponseResultStatusFailedFileDoesNotExist FileImportFromCloudResponseResultStatus = "FAILED_FILE_DOES_NOT_EXIST"`

      - `const FileImportFromCloudResponseResultStatusFailedInvalidPermissions FileImportFromCloudResponseResultStatus = "FAILED_INVALID_PERMISSIONS"`

      - `const FileImportFromCloudResponseResultStatusFailedUnknownError FileImportFromCloudResponseResultStatus = "FAILED_UNKNOWN_ERROR"`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  response, err := client.Files.ImportFromCloud(context.TODO(), sgpdev.FileImportFromCloudParams{
    Files: []sgpdev.FileImportFromCloudParamsFile{sgpdev.FileImportFromCloudParamsFile{
      Container: "container",
      FileType: "file_type",
      Filename: "filename",
      Filepath: "filepath",
    }},
  })
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", response.Results)
}
```

#### Response

```json
{
  "results": [
    {
      "file": {
        "id": "id",
        "created_at": "2019-12-27T18:11:19.117Z",
        "created_by": {
          "id": "id",
          "type": "user",
          "object": "identity"
        },
        "filename": "filename",
        "md5_checksum": "md5_checksum",
        "mime_type": "mime_type",
        "size": 0,
        "duration_seconds": 0,
        "object": "file",
        "tags": {
          "foo": "bar"
        }
      },
      "status": "SUCCESS"
    }
  ]
}
```

## List files

`client.Files.List(ctx, params) (*CursorPage[SGPFile], error)`

**get** `/v5/files`

List the account's files with pagination.

Optionally filter by `filename` (case-insensitive partial match). Results
are scoped to the files the caller is authorized to read. Files marked hidden
(internal or service-owned artifacts) are excluded from this listing but
remain retrievable by id. Returns file metadata only, not content.

### Parameters

- `params FileListParams`

  - `EndingBefore param.Field[string]`

    Query param

  - `Filename param.Field[string]`

    Query param: Filter files by filename (case-insensitive partial match)

  - `Limit param.Field[int64]`

    Query param

  - `SortBy param.Field[string]`

    Query param

  - `SortOrder param.Field[SortOrder]`

    Query param

  - `StartingAfter param.Field[string]`

    Query param

  - `XProjectID param.Field[string]`

    Header param

### Returns

- `type SGPFile struct{…}`

  - `ID string`

    The unique identifier of the entity.

  - `CreatedAt Time`

    The date and time when the entity was created in ISO format.

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Filename string`

  - `Md5Checksum string`

  - `MimeType string`

  - `Size int64`

  - `DurationSeconds int64`

  - `Object SGPFileObject`

    - `const SGPFileObjectFile SGPFileObject = "file"`

  - `Tags map[string, any]`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  page, err := client.Files.List(context.TODO(), sgpdev.FileListParams{

  })
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", page)
}
```

#### Response

```json
{
  "has_more": true,
  "items": [
    {
      "id": "id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "created_by": {
        "id": "id",
        "type": "user",
        "object": "identity"
      },
      "filename": "filename",
      "md5_checksum": "md5_checksum",
      "mime_type": "mime_type",
      "size": 0,
      "duration_seconds": 0,
      "object": "file",
      "tags": {
        "foo": "bar"
      }
    }
  ],
  "total": 0,
  "limit": 0,
  "object": "list"
}
```

## Update a file

`client.Files.Update(ctx, fileID, params) (*SGPFile, error)`

**patch** `/v5/files/{file_id}`

Update a file's mutable metadata by id.

Only the file's `tags` can be modified; filename, content, size, and other
attributes are immutable through this endpoint. The supplied tags replace the
file's existing tags. Returns the updated file metadata.

### Parameters

- `fileID string`

- `params FileUpdateParams`

  - `Tags param.Field[map[string, any]]`

    Body param

  - `XProjectID param.Field[string]`

    Header param

### Returns

- `type SGPFile struct{…}`

  - `ID string`

    The unique identifier of the entity.

  - `CreatedAt Time`

    The date and time when the entity was created in ISO format.

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Filename string`

  - `Md5Checksum string`

  - `MimeType string`

  - `Size int64`

  - `DurationSeconds int64`

  - `Object SGPFileObject`

    - `const SGPFileObjectFile SGPFileObject = "file"`

  - `Tags map[string, any]`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  sgpFile, err := client.Files.Update(
    context.TODO(),
    "file_id",
    sgpdev.FileUpdateParams{

    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", sgpFile.ID)
}
```

#### Response

```json
{
  "id": "id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "filename": "filename",
  "md5_checksum": "md5_checksum",
  "mime_type": "mime_type",
  "size": 0,
  "duration_seconds": 0,
  "object": "file",
  "tags": {
    "foo": "bar"
  }
}
```

## Get file metadata

`client.Files.Get(ctx, fileID, query) (*SGPFile, error)`

**get** `/v5/files/{file_id}`

Retrieve a single file's metadata by id.

Returns the file record (id, filename, MIME type, size, tags, and related
fields) but not the file's bytes; use the content endpoint to download the
bytes.

### Parameters

- `fileID string`

- `query FileGetParams`

  - `XProjectID param.Field[string]`

### Returns

- `type SGPFile struct{…}`

  - `ID string`

    The unique identifier of the entity.

  - `CreatedAt Time`

    The date and time when the entity was created in ISO format.

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Filename string`

  - `Md5Checksum string`

  - `MimeType string`

  - `Size int64`

  - `DurationSeconds int64`

  - `Object SGPFileObject`

    - `const SGPFileObjectFile SGPFileObject = "file"`

  - `Tags map[string, any]`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  sgpFile, err := client.Files.Get(
    context.TODO(),
    "file_id",
    sgpdev.FileGetParams{

    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", sgpFile.ID)
}
```

#### Response

```json
{
  "id": "id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "filename": "filename",
  "md5_checksum": "md5_checksum",
  "mime_type": "mime_type",
  "size": 0,
  "duration_seconds": 0,
  "object": "file",
  "tags": {
    "foo": "bar"
  }
}
```

## Delete a file

`client.Files.Delete(ctx, fileID, body) (*FileDeleteResponse, error)`

**delete** `/v5/files/{file_id}`

Delete a file by id, removing its database record.

This is a hard delete: the file's row is removed from the database, not
soft-archived. The underlying stored object is deleted only when no other
file record still references the same stored content (identical checksum and
MIME type); when another record shares the blob, the blob is retained. If the
id refers to an incomplete multipart upload placeholder, its staged parts are
aborted instead. Returns a confirmation carrying the deleted file's id.

### Parameters

- `fileID string`

- `body FileDeleteParams`

  - `XProjectID param.Field[string]`

### Returns

- `type FileDeleteResponse struct{…}`

  - `ID string`

  - `Deleted bool`

  - `Object FileDeleteResponseObject`

    - `const FileDeleteResponseObjectFile FileDeleteResponseObject = "file"`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  file, err := client.Files.Delete(
    context.TODO(),
    "file_id",
    sgpdev.FileDeleteParams{

    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", file.ID)
}
```

#### Response

```json
{
  "id": "id",
  "deleted": true,
  "object": "file"
}
```

## Domain Types

### SGP File

- `type SGPFile struct{…}`

  - `ID string`

    The unique identifier of the entity.

  - `CreatedAt Time`

    The date and time when the entity was created in ISO format.

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Filename string`

  - `Md5Checksum string`

  - `MimeType string`

  - `Size int64`

  - `DurationSeconds int64`

  - `Object SGPFileObject`

    - `const SGPFileObjectFile SGPFileObject = "file"`

  - `Tags map[string, any]`

# Content

## Download file content

`client.Files.Content.Get(ctx, fileID, query) (*FileContentGetResponse, error)`

**get** `/v5/files/{file_id}/content`

Download the raw bytes of a file by id.

Streams the stored object's content back directly (not a redirect or signed
URL), with the response Content-Type set to the file's stored MIME type and
Content-Disposition set to attachment. Use the metadata endpoint for size,
filename, and other attributes.

### Parameters

- `fileID string`

- `query FileContentGetParams`

  - `XProjectID param.Field[string]`

### Returns

- `type FileContentGetResponse interface{…}`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  content, err := client.Files.Content.Get(
    context.TODO(),
    "file_id",
    sgpdev.FileContentGetParams{

    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", content)
}
```

#### Response

```json
{}
```
