---
name: "PrivateMessages Api v1"
last_updated: 2026-06-15T23:39:17Z
type: legacy
api_base_url: "https://privatemessages.roblox.com"
versions: [v1]
endpoints: 9
auth: [cookie]
---

# PrivateMessages 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://privatemessages.roblox.com`
**Versions:** v1

## Endpoints

### GET `/v1/announcements`

Migrate from RobloxWebsite project, return news notification for Private Message page

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.GetAnnouncementsResponse`
- `400`: 2: Message does not exist or the current user is not authorized to view it.
- `401`: 0: Authorization has been denied for this request.

**Response fields** (`Roblox.PrivateMessages.Api.Models.GetAnnouncementsResponse`)

See [Roblox.PrivateMessages.Api.Models.GetAnnouncementsResponse](#roblox-privatemessages-api-models-getannouncementsresponse) in Models.

**Response example:**
```json
{
  "collection": [
    {
      "id": "...",
      "sender": "...",
      "subject": "...",
      "body": "...",
      "created": "...",
      "updated": "..."
    }
  ],
  "totalCollectionSize": 0
}
```

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

**Example:**
```bash
curl -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://privatemessages.roblox.com/v1/announcements"
```

### GET `/v1/announcements/metadata`

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.AnnouncementsMetadataResponse`
- `401`: 0: Authorization has been denied for this request.

**Response fields** (`Roblox.PrivateMessages.Api.Models.AnnouncementsMetadataResponse`)

See [Roblox.PrivateMessages.Api.Models.AnnouncementsMetadataResponse](#roblox-privatemessages-api-models-announcementsmetadataresponse) in Models.

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

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

**Example:**
```bash
curl -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://privatemessages.roblox.com/v1/announcements/metadata"
```

### GET `/v1/messages`

Gets a user's messages.

**Parameters:**

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `pageNumber` | query | `integer (int32)` | No |  |
| `pageSize` | query | `integer (int32)` | No |  |
| `messageTab` | query | `string` | No | Valid values: `Inbox`, `Sent`, `Archive` |

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.GetMessagesResponse`
- `401`: 0: Authorization has been denied for this request.

**Response fields** (`Roblox.PrivateMessages.Api.Models.GetMessagesResponse`)

See [Roblox.PrivateMessages.Api.Models.GetMessagesResponse](#roblox-privatemessages-api-models-getmessagesresponse) in Models.

**Response example:**
```json
{
  "collection": [
    {
      "id": "...",
      "sender": "...",
      "recipient": "...",
      "subject": "...",
      "body": "...",
      "created": "..."
    }
  ],
  "totalCollectionSize": 0,
  "totalPages": 0,
  "pageNumber": 0
}
```

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

**Example:**
```bash
curl -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://privatemessages.roblox.com/v1/messages"
```

### GET `/v1/messages/{messageId}`

Gets a message's details.

**Parameters:**

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `messageId` | path | `integer (int64)` | Yes |  |

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.MessageDetailsResponse`
- `400`: 2: Message does not exist or the current user is not authorized to view it.
- `401`: 0: Authorization has been denied for this request.

**Response fields** (`Roblox.PrivateMessages.Api.Models.MessageDetailsResponse`)

See [Roblox.PrivateMessages.Api.Models.MessageDetailsResponse](#roblox-privatemessages-api-models-messagedetailsresponse) in Models.

**Response example:**
```json
{
  "id": 0,
  "sender": {
    "hasVerifiedBadge": false,
    "id": 0,
    "name": "string",
    "displayName": "string"
  },
  "recipient": {
    "hasVerifiedBadge": false,
    "id": 0,
    "name": "string",
    "displayName": "string"
  },
  "subject": "string",
  "body": "string",
  "created": "2024-01-01T00:00:00Z"
}
```

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

**Example:**
```bash
curl -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://privatemessages.roblox.com/v1/messages/{MESSAGEID}"
```

### GET `/v1/messages/unread/count`

Gets unread messages for the authenticated user.

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.UnreadMessagesCountResponse`
- `401`: 0: Authorization has been denied for this request.

**Response fields** (`Roblox.PrivateMessages.Api.Models.UnreadMessagesCountResponse`)

See [Roblox.PrivateMessages.Api.Models.UnreadMessagesCountResponse](#roblox-privatemessages-api-models-unreadmessagescountresponse) in Models.

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

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

**Example:**
```bash
curl -H "Authorization: Bearer $ROBLOX_ACCESS_TOKEN" \
  "https://privatemessages.roblox.com/v1/messages/unread/count"
```

### POST `/v1/messages/archive`

Archives a batch of messages.

**Request Body:** `application/json` — Type: `Roblox.PrivateMessages.Api.Models.BatchMessagesRequest`

See [Roblox.PrivateMessages.Api.Models.BatchMessagesRequest](#roblox-privatemessages-api-models-batchmessagesrequest) in Models.

**Request example:**
```json
{
  "messageIds": [
    0
  ]
}
```

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.BatchMessagesResponse`
- `400`: 5: Too many ids in a batch request.
- `401`: 0: Authorization has been denied for this request.
- `403`: 0: Token Validation Failed

**Response fields** (`Roblox.PrivateMessages.Api.Models.BatchMessagesResponse`)

See [Roblox.PrivateMessages.Api.Models.BatchMessagesResponse](#roblox-privatemessages-api-models-batchmessagesresponse) in Models.

**Response example:**
```json
{
  "failedMessages": [
    {
      "messageId": "...",
      "errorMessage": "..."
    }
  ]
}
```

**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://privatemessages.roblox.com/v1/messages/archive" \
  -H "Content-Type: application/json" \
  -d '{
  "messageIds": [
    0
  ]
}'
```

### POST `/v1/messages/mark-read`

Marks a batch of messages as read.

**Request Body:** `application/json` — Type: `Roblox.PrivateMessages.Api.Models.BatchMessagesRequest`

See [Roblox.PrivateMessages.Api.Models.BatchMessagesRequest](#roblox-privatemessages-api-models-batchmessagesrequest) in Models.

**Request example:**
```json
{
  "messageIds": [
    0
  ]
}
```

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.BatchMessagesResponse`
- `400`: 5: Too many ids in a batch request.
- `401`: 0: Authorization has been denied for this request.
- `403`: 0: Token Validation Failed

**Response fields** (`Roblox.PrivateMessages.Api.Models.BatchMessagesResponse`)

See [Roblox.PrivateMessages.Api.Models.BatchMessagesResponse](#roblox-privatemessages-api-models-batchmessagesresponse) in Models.

**Response example:**
```json
{
  "failedMessages": [
    {
      "messageId": "...",
      "errorMessage": "..."
    }
  ]
}
```

**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://privatemessages.roblox.com/v1/messages/mark-read" \
  -H "Content-Type: application/json" \
  -d '{
  "messageIds": [
    0
  ]
}'
```

### POST `/v1/messages/mark-unread`

Marks a batch of messages as unread.

**Request Body:** `application/json` — Type: `Roblox.PrivateMessages.Api.Models.BatchMessagesRequest`

See [Roblox.PrivateMessages.Api.Models.BatchMessagesRequest](#roblox-privatemessages-api-models-batchmessagesrequest) in Models.

**Request example:**
```json
{
  "messageIds": [
    0
  ]
}
```

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.BatchMessagesResponse`
- `400`: 5: Too many ids in a batch request.
- `401`: 0: Authorization has been denied for this request.
- `403`: 0: Token Validation Failed

**Response fields** (`Roblox.PrivateMessages.Api.Models.BatchMessagesResponse`)

See [Roblox.PrivateMessages.Api.Models.BatchMessagesResponse](#roblox-privatemessages-api-models-batchmessagesresponse) in Models.

**Response example:**
```json
{
  "failedMessages": [
    {
      "messageId": "...",
      "errorMessage": "..."
    }
  ]
}
```

**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://privatemessages.roblox.com/v1/messages/mark-unread" \
  -H "Content-Type: application/json" \
  -d '{
  "messageIds": [
    0
  ]
}'
```

### POST `/v1/messages/unarchive`

Unarchives a batch of messages.

**Request Body:** `application/json` — Type: `Roblox.PrivateMessages.Api.Models.BatchMessagesRequest`

See [Roblox.PrivateMessages.Api.Models.BatchMessagesRequest](#roblox-privatemessages-api-models-batchmessagesrequest) in Models.

**Request example:**
```json
{
  "messageIds": [
    0
  ]
}
```

**Responses:**

- `200`: OK → `Roblox.PrivateMessages.Api.Models.BatchMessagesResponse`
- `400`: 5: Too many ids in a batch request.
- `401`: 0: Authorization has been denied for this request.
- `403`: 0: Token Validation Failed

**Response fields** (`Roblox.PrivateMessages.Api.Models.BatchMessagesResponse`)

See [Roblox.PrivateMessages.Api.Models.BatchMessagesResponse](#roblox-privatemessages-api-models-batchmessagesresponse) in Models.

**Response example:**
```json
{
  "failedMessages": [
    {
      "messageId": "...",
      "errorMessage": "..."
    }
  ]
}
```

**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://privatemessages.roblox.com/v1/messages/unarchive" \
  -H "Content-Type: application/json" \
  -d '{
  "messageIds": [
    0
  ]
}'
```

## Models

### Roblox.PrivateMessages.Api.Models.AnnouncementsDetailsResponse

A message details response.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `id` | `integer` | No | The message's ID. |
| `sender` | `Roblox.PrivateMessages.Api.Models.VerifiedSkinnyUserResponse` | No |  |
| `subject` | `string` | No | The subject of the message. |
| `body` | `string` | No | The body of the message. |
| `created` | `string` | No | When the message was created. |
| `updated` | `string` | No | When the message was last updated. |

### Roblox.PrivateMessages.Api.Models.AnnouncementsMetadataResponse

A message details response.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `numOfAnnouncements` | `integer` | No | Number of incoming news |

### Roblox.PrivateMessages.Api.Models.BatchMessagesRequest

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `messageIds` | `integer[]` | No |  |

### Roblox.PrivateMessages.Api.Models.BatchMessagesResponse

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `failedMessages` | `Roblox.PrivateMessages.Api.Models.FailedMessageResponse[]` | No |  |

### Roblox.PrivateMessages.Api.Models.FailedMessageResponse

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `messageId` | `integer` | No |  |
| `errorMessage` | `string` | No |  |

### Roblox.PrivateMessages.Api.Models.GetAnnouncementsResponse

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `collection` | `Roblox.PrivateMessages.Api.Models.AnnouncementsDetailsResponse[]` | No |  |
| `totalCollectionSize` | `integer` | No |  |

### Roblox.PrivateMessages.Api.Models.GetMessagesResponse

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `collection` | `Roblox.PrivateMessages.Api.Models.MessageDetailsResponse[]` | No |  |
| `totalCollectionSize` | `integer` | No |  |
| `totalPages` | `integer` | No |  |
| `pageNumber` | `integer` | No |  |

### Roblox.PrivateMessages.Api.Models.MessageDetailsResponse

A message details response.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `id` | `integer` | No | The message's ID. |
| `sender` | `Roblox.PrivateMessages.Api.Models.VerifiedSkinnyUserResponse` | No |  |
| `recipient` | `Roblox.PrivateMessages.Api.Models.VerifiedSkinnyUserResponse` | No |  |
| `subject` | `string` | No | The subject of the message. |
| `body` | `string` | No | The body of the message. |
| `created` | `string` | No | When the message was created. |
| `updated` | `string` | No | When the message was last updated. |
| `isRead` | `boolean` | No | Whether or not the message has been read. |
| `isSystemMessage` | `boolean` | No | Whether or not the message is a system message. |
| `isReportAbuseDisplayed` | `boolean` | No | Whether or not the abuse report link is displayed for the message. |

### Roblox.PrivateMessages.Api.Models.UnreadMessagesCountResponse

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `count` | `integer` | No |  |

### Roblox.PrivateMessages.Api.Models.VerifiedSkinnyUserResponse

A response model representing user basic information and the user's verified badge status.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `hasVerifiedBadge` | `boolean` | No | Whether the user has a verified badge. |
| `id` | `integer` | No |  |
| `name` | `string` | No |  |
| `displayName` | `string` | No |  |