---
name: "Publish Api v1"
last_updated: 2026-06-11T23:12:12Z
type: legacy
api_base_url: "https://publish.roblox.com"
versions: [v1]
endpoints: 6
auth: [cookie]
---

# Publish Api v1

> **Warning:** Legacy APIs with cookie authentication can incorporate breaking changes without notice. We don't recommend them for production applications.

**Base URL:** `https://publish.roblox.com`
**Versions:** v1

## Endpoints

### GET `/v1/asset-quotas`

List asset quotas of the given resource type and asset type.

**Parameters:**

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `resourceType` | query | `string` | Yes | Resource type of the asset quota |
| `assetType` | query | `string` | Yes | Asset type of the asset quota |
| `useDummyData` | query | `boolean` | No | Use dummy data for testing. This is for internal use only |

**Responses:**

- `200`: OK → `Roblox.Publish.Api.AssetQuotasResponse`
- `400`: 7: The asset type is not appropriate for this request. 8: The resource type is not appropriate for this request.
- `401`: 0: Authorization has been denied for this request.
- `500`: 0: Reserved for base level errors. Do not use in your endpoint directly, do not document.

**Response fields** (`Roblox.Publish.Api.AssetQuotasResponse`)

See [Roblox.Publish.Api.AssetQuotasResponse](#roblox-publish-api-assetquotasresponse) in Models.

**Response example:**
```json
{
  "quotas": [
    {
      "duration": "...",
      "usage": "...",
      "capacity": "...",
      "expirationTime": "..."
    }
  ]
}
```

**Error handling:** `401`: Check that your API key/token is valid and not expired. 

**Example:**
```bash
curl -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://publish.roblox.com/v1/asset-quotas?resourceType={VALUE}&assetType={VALUE}"
```

### POST `/v1/audio`

Published an audio file and returns the new asset info.

**Request Body:** `application/json` — Type: `Roblox.Publish.Api.UploadAudioRequest`

See [Roblox.Publish.Api.UploadAudioRequest](#roblox-publish-api-uploadaudiorequest) in Models.

**Request example:**
```json
{
  "name": "string",
  "file": "string",
  "groupId": 0,
  "paymentSource": "string",
  "estimatedFileSize": 0,
  "estimatedDuration": 0
}
```

**Responses:**

- `200`: OK → `Roblox.Publish.Api.PublishAudioResponse`
- `400`: 3: The request did not contain a file to be uploaded. 4: The file in the request is too large. 5: The duration of the audio file is too long. 7: Failed to parse the file. 8: The file type is not supported. 9: The file is corrupted 11: Missing permissions to spend group funds. 14: The user/group does not have suffiecient funds to publish. 14: The user/group does not have suffiecient funds to publish. 15: The audio file has already been reviewed and rejected. 18: Too many requests. Try again later. 20: Error while trying to purchase the product. 22: The file size estimation error was greater than the acceptable margin of error. 23: The duration estimation error was greater than the acceptable margin of error. 24: Asset privacy is invalid. 29: Invalid argument in the request.
- `401`: 0: Authorization has been denied for this request. 1: The request did not include an authorization.
- `403`: 0: Token Validation Failed
- `500`: 19: Asset creation was unavailable. Please try again.

**Response fields** (`Roblox.Publish.Api.PublishAudioResponse`)

See [Roblox.Publish.Api.PublishAudioResponse](#roblox-publish-api-publishaudioresponse) in Models.

**Response example:**
```json
{
  "Id": 0,
  "Name": "string"
}
```

**Error handling:** `401`: Check that your API key/token is valid and not expired. `403`: Verify your API key has the required scopes listed above. 

**Example:**
```bash
curl -X POST -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://publish.roblox.com/v1/audio" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "file": "string",
  "groupId": 0,
  "paymentSource": "string",
  "estimatedFileSize": 0,
  "estimatedDuration": 0
}'
```

### POST `/v1/audio/verify`

Verifies an audio file and returns a product that you can purchase to publish the audio file.

**Request Body:** `application/json` — Type: `Roblox.Publish.Api.VerifyAudioRequest`

See [Roblox.Publish.Api.VerifyAudioRequest](#roblox-publish-api-verifyaudiorequest) in Models.

**Request example:**
```json
{
  "name": "string",
  "file": "string",
  "groupId": 0,
  "paymentSource": "string",
  "fileSize": 0,
  "duration": 0
}
```

**Responses:**

- `200`: OK → `Roblox.Publish.Api.VerifyAudioResponse`
- `400`: 3: The request did not contain a file to be uploaded. 4: The file in the request is too large. 5: The duration of the audio file is too long. 7: Failed to parse the file. 8: The file type is not supported. 9: The file is corrupted 18: Too many requests. Try again later.
- `401`: 0: Authorization has been denied for this request. 1: The request did not include an authorization.
- `403`: 0: Token Validation Failed

**Response fields** (`Roblox.Publish.Api.VerifyAudioResponse`)

See [Roblox.Publish.Api.VerifyAudioResponse](#roblox-publish-api-verifyaudioresponse) in Models.

**Response example:**
```json
{
  "name": "string",
  "price": 0,
  "balance": 0,
  "canAfford": false
}
```

**Error handling:** `401`: Check that your API key/token is valid and not expired. `403`: Verify your API key has the required scopes listed above. 

**Example:**
```bash
curl -X POST -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://publish.roblox.com/v1/audio/verify" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "file": "string",
  "groupId": 0,
  "paymentSource": "string",
  "fileSize": 0,
  "duration": 0
}'
```

### POST `/v1/badges/{badgeId}/icon`

Overwrites a badge icon with a new one.

**Parameters:**

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `badgeId` | path | `integer (int64)` | Yes | The badge Id. |
| `Files` | formData | `file` | No |  |

**Responses:**

- `200`: OK → `Roblox.Publish.Api.UploadResponse`
- `400`: 2: File not present in request. 12: Name or description is moderated.
- `401`: 0: Authorization has been denied for this request.
- `403`: 0: Token Validation Failed 5: You do not have permission to manage this item.
- `404`: 4: Target item is invalid or does not exist.
- `429`: 3: You're uploading too much, please wait and try again later.

**Response fields** (`Roblox.Publish.Api.UploadResponse`)

See [Roblox.Publish.Api.UploadResponse](#roblox-publish-api-uploadresponse) in Models.

**Response example:**
```json
{
  "targetId": 0
}
```

**Error handling:** `429`: Retry with exponential backoff (start at 1s). `401`: Check that your API key/token is valid and not expired. `403`: Verify your API key has the required scopes listed above. 

**Example:**
```bash
curl -X POST -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://publish.roblox.com/v1/badges/{BADGEID}/icon"
```

### POST `/v1/games/{gameId}/thumbnail/image`

Uploads a game thumbnail.

**Parameters:**

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `gameId` | path | `integer (int64)` | Yes | The universe Id. |
| `Files` | formData | `file` | No |  |

**Responses:**

- `200`: OK → `Roblox.Publish.Api.UploadResponse`
- `400`: 1: File uploaded does not match known image format. Try converting to png. 2: File not present in request.
- `401`: 0: Authorization has been denied for this request.
- `403`: 0: Token Validation Failed 5: You do not have permission to manage this item.
- `404`: 4: Target item is invalid or does not exist.
- `429`: 3: You're uploading too much, please wait and try again later.

**Response fields** (`Roblox.Publish.Api.UploadResponse`)

See [Roblox.Publish.Api.UploadResponse](#roblox-publish-api-uploadresponse) in Models.

**Response example:**
```json
{
  "targetId": 0
}
```

**Error handling:** `429`: Retry with exponential backoff (start at 1s). `401`: Check that your API key/token is valid and not expired. `403`: Verify your API key has the required scopes listed above. 

**Example:**
```bash
curl -X POST -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://publish.roblox.com/v1/games/{GAMEID}/thumbnail/image"
```

### POST `/v1/plugins/{pluginId}/icon`

Overwrites a plugin icon with a new one.

**Parameters:**

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `pluginId` | path | `integer (int64)` | Yes | The plugin Id. |
| `Files` | formData | `file` | No |  |

**Responses:**

- `200`: OK → `Roblox.Publish.Api.UploadResponse`
- `400`: 2: File not present in request.
- `401`: 0: Authorization has been denied for this request.
- `403`: 0: Token Validation Failed 5: You do not have permission to manage this item.
- `404`: 4: Target item is invalid or does not exist.
- `429`: 3: You're uploading too much, please wait and try again later.

**Response fields** (`Roblox.Publish.Api.UploadResponse`)

See [Roblox.Publish.Api.UploadResponse](#roblox-publish-api-uploadresponse) in Models.

**Response example:**
```json
{
  "targetId": 0
}
```

**Error handling:** `429`: Retry with exponential backoff (start at 1s). `401`: Check that your API key/token is valid and not expired. `403`: Verify your API key has the required scopes listed above. 

**Example:**
```bash
curl -X POST -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://publish.roblox.com/v1/plugins/{PLUGINID}/icon"
```

## Models

### Roblox.Publish.Api.AssetQuota

Model for asset quota.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `duration` | `string` | No | Duration type of the quota. |
| `usage` | `integer` | No | Current usage of the quota. |
| `capacity` | `integer` | No | Capacity of the quota. |
| `expirationTime` | `string` | No | Expiration time of current usage limit. |

### Roblox.Publish.Api.AssetQuotasResponse

Response model for asset quotas.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `quotas` | `Roblox.Publish.Api.AssetQuota[]` | No | A list of quotas. |

### Roblox.Publish.Api.PublishAudioResponse

Response model for publish audio.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `Id` | `integer` | No | Id of the published asset. |
| `Name` | `string` | No | Name of the published asset. |

### Roblox.Publish.Api.UploadAudioRequest

A request model for uploading an audio file.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `name` | `string` | No | Name for the audio file. |
| `file` | `string` | No | File to be uploaded. Formatted as a base64 string. |
| `groupId` | `integer` | No | Id of the group you are publishing the audio asset for. Null if not publishing under a group. |
| `paymentSource` | `string` | No | The source of funds for payment.   User: Use personal funds of authenticated user.   Group: Use group funds from Roblox.Publish.Api.UploadAudioRequest.GroupId.   Null/Empty: Will default to authenticated user funds. |
| `estimatedFileSize` | `integer` | No | Estimated file size of the audio file in bytes. |
| `estimatedDuration` | `number` | No | Estimated duration of the audio file in seconds. |
| `assetPrivacy` | `1 \| 2` | No | The asset privacy of the audio asset. |

### Roblox.Publish.Api.UploadResponse

A response used when an upload has completed.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `targetId` | `integer` | No | The target Id of the uploaded item. |

### Roblox.Publish.Api.VerifyAudioRequest

Request model to publish an audio asset.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `name` | `string` | No | Gets or sets the name of the audio asset. |
| `file` | `string` | No | File to be uploaded. Formatted as a base64 string. |
| `groupId` | `integer` | No | Gets or sets the ID of the group if applicable. Optional. |
| `paymentSource` | `string` | No | Gets or sets the payment source. 'User' or 'Group'. Required if Group ID is set. |
| `fileSize` | `integer` | No | Gets or sets the size of the audio file in bytes. |
| `duration` | `number` | No | Gets or sets the duration of the audio in seconds. |

### Roblox.Publish.Api.VerifyAudioResponse

Response model for verify audio endpoint.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `name` | `string` | No | Name of the audio file. |
| `price` | `integer` | No | Price in robux to publish the audio file. |
| `balance` | `integer` | No | User's current Robux balance. |
| `canAfford` | `boolean` | No | Boolean, true if the user can afford to purchase the publishing of the audio file. |