# Upload a media asset

_NgCms / Media Assets_

`POST /ng-cms/media/{projectId}`

## Parameters

- `projectId` (string, required) — The unique identifier of the project (bucket)
- `file` (file, required) — The file to upload. Maximum size is 10 MB. Must be sent as multipart/form-data.
- `title` (string, optional) — Human-readable title for the asset. Defaults to the filename (without extension) if omitted.
- `description` (string, optional) — Optional description of the media asset.

## Responses

### `201` — File uploaded and media asset created successfully. Returns the new asset ID.

Type: `ApiResponse<string>`

- `success` (boolean) — Indicates whether the request was successful
- `result` (string) — The ID of the newly created media asset
- `errors` (ErrorDetail[]) — List of errors (empty on success)

### `400` — Bad Request. No file was provided or the file is empty.


### `401` — Unauthorized. A valid bearer token is required.


### `412` — Precondition Failed. The project's current plan does not allow access to this resource, or payment is required to proceed.


### `500` — Unexpected server error.

Type: `ApiResponse<T>`

- `success` (boolean) — Always false
- `errors` (ErrorDetail[]) — List of server-side errors
  - `correlationId` (string) — Unique ID for tracing the error
  - `message` (string) — Error message
  - `stack` (string) — Stack trace (non-production only)


## Code Examples

### curl

```curl
curl --request POST \
  --url https://apis-spb.konso.io/ng-cms/media/{projectId} \
  --header 'Authorization: Bearer <token>' \
  --form 'file=@/path/to/image.jpg' \
  --form 'title=Hero Image' \
  --form 'description=Main banner image'
```

### javascript

```js
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('title', 'Hero Image');
formData.append('description', 'Main banner image');

const options = {
  method: 'POST',
  headers: { Authorization: 'Bearer <token>' },
  body: formData
};

fetch('https://apis-spb.konso.io/ng-cms/media/{projectId}', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));
```

### dotnet

```dotnet
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "<token>");

using var form = new MultipartFormDataContent();
var fileBytes = await File.ReadAllBytesAsync("/path/to/image.jpg");
form.Add(new ByteArrayContent(fileBytes), "file", "image.jpg");
form.Add(new StringContent("Hero Image"), "title");
form.Add(new StringContent("Main banner image"), "description");

var response = await client.PostAsync("https://apis-spb.konso.io/ng-cms/media/{projectId}", form);
var result = await response.Content.ReadFromJsonAsync<ApiResponse<string>>();
```

### python

```python
import requests

url = "https://apis-spb.konso.io/ng-cms/media/{projectId}"
headers = { "Authorization": "Bearer <token>" }

with open("/path/to/image.jpg", "rb") as f:
    files = { "file": ("image.jpg", f, "image/jpeg") }
    data = { "title": "Hero Image", "description": "Main banner image" }
    response = requests.post(url, headers=headers, files=files, data=data)

print(response.json())
```

### Request Body Example

```json
{
  "projectId": "example-string",
  "file": "example-value",
  "title": "example-string",
  "description": "example-string"
}
```

### Response Example (201)

```json
{
  "success": true,
  "result": "ma_f1e2d3c4b5a6",
  "errors": []
}
```

## Repositories

- [konso-cms-nodejs](https://gitverse.ru/konso/konso-cms-nodejs)
- [konso-cms-dotnet](https://gitverse.ru/konso/konso-cms-dotnet)

## Packages

- `dotnet add package Konso.Clients.Cms` — [Konso.Clients.Cms](https://nugetprodusnc-northcentralus-01.regional.azure-api.net/packages/Konso.Clients.Cms)
- `npm install @konso/cms-client` — [@konso/cms-client](https://www.npmjs.com/package/@konso/cms-client)
