Media

Avatars (profile pictures) and custom emotes

The Media API handles profile pictures (avatars) and custom emotes with thumbnail generation.

Avatars

Avatar Sizes

Size Description
cropped Full cropped version
1600 Large thumbnail
512 Medium thumbnail
256 Default size
128 Small thumbnail
64 Icon size

Get User Avatar

Get the avatar URL for any user (public endpoint).

GET /v1/users/{userID}/avatar?size=256

Query Parameters:

Param Default Description
size 256 Thumbnail size

Response:

{
  "url": "https://cdn.ocvr.net/...",
  "expires_at": 1703533600
}

Error Codes:

Code Description
AVATAR_NOT_FOUND User has no avatar
AVATAR_NOT_READY Still processing
INVALID_SIZE Invalid size parameter

Set Avatar

Set your profile picture from an uploaded file.

PUT /v1/users/me/avatar
Authorization: Bearer {token}
{
  "file_id": "999888777"
}

Response: 204 No Content

Notes:

  • The file must be a profile_pic asset type
  • The file must be in ready processing state
  • Upload via Uploads API first

Error Codes:

Code Description
FILE_NOT_FOUND File doesn't exist
FILE_NOT_PROFILE_PIC Not a profile_pic asset
FILE_NOT_READY Still processing

Remove Avatar

Remove your profile picture.

DELETE /v1/users/me/avatar
Authorization: Bearer {token}

Response: 204 No Content

Notes:

  • The profile_pic file is not deleted
  • You can reassign it later

Re-crop Avatar

Re-crop your avatar with different coordinates.

POST /v1/users/me/avatar/recrop
Authorization: Bearer {token}
{
  "crop_x": 100,
  "crop_y": 50,
  "crop_w": 400,
  "crop_h": 400
}

Response (202 Accepted):

{
  "status": "processing",
  "message": "Avatar recrop queued"
}

Notes:

  • Queues a processing job to regenerate thumbnails
  • Avatar will be temporarily unavailable during processing
  • Poll the avatar endpoint until ready

Error Codes:

Code Description
AVATAR_NOT_FOUND No avatar to recrop
RECROP_INVALID Invalid crop parameters

Emotes

Emote Sizes

Size Description
full Original size
256 Large thumbnail
128 Default size
64 Small size

List Emotes

List your custom emotes.

GET /v1/emotes?limit=100&cursor={cursor}
Authorization: Bearer {token}

Query Parameters:

Param Default Description
limit 100 Max results (1-500)
cursor - Pagination cursor

Response:

{
  "emotes": [
    {
      "id": "111222333",
      "owner_id": "12345",
      "name": "cool_emote.gif",
      "shortcode": "cool",
      "size_bytes": 262144,
      "mime_type": "image/gif",
      "processing_state": "ready",
      "created_at": 1703520000,
      "updated_at": 1703520000
    }
  ],
  "next_cursor": null
}

Get Emote

Get emote details.

GET /v1/emotes/{emoteID}
Authorization: Bearer {token}

Response:

{
  "id": "111222333",
  "owner_id": "12345",
  "name": "cool_emote.gif",
  "shortcode": "cool",
  "size_bytes": 262144,
  "mime_type": "image/gif",
  "processing_state": "ready",
  "created_at": 1703520000,
  "updated_at": 1703520000
}

Get Emote URL

Get presigned URL for an emote.

GET /v1/emotes/{emoteID}/url?size=128
Authorization: Bearer {token}

Query Parameters:

Param Default Description
size 128 Thumbnail size (full, 256, 128, 64)

Response:

{
  "url": "https://cdn.ocvr.net/...",
  "expires_at": 1703533600
}

Access:

  • Owner can always access their emotes
  • Public emotes can be accessed by anyone

Error Codes:

Code Description
EMOTE_NOT_FOUND Emote doesn't exist
EMOTE_NOT_READY Still processing
INVALID_SIZE Invalid size parameter

Update Emote

Update emote shortcode.

PUT /v1/emotes/{emoteID}
Authorization: Bearer {token}
{
  "shortcode": "new_shortcode"
}

Response:

{
  "id": "111222333",
  "owner_id": "12345",
  "name": "cool_emote.gif",
  "shortcode": "new_shortcode",
  "size_bytes": 262144,
  "mime_type": "image/gif",
  "processing_state": "ready",
  "created_at": 1703520000,
  "updated_at": 1703535000
}

Shortcode Rules:

  • 2-32 characters
  • Letters, numbers, and underscores only

Error Codes:

Code Description
EMOTE_NOT_OWNER Not your emote
SHORTCODE_INVALID Invalid shortcode format

Delete Emote

Delete an emote.

DELETE /v1/emotes/{emoteID}
Authorization: Bearer {token}

Response: 204 No Content

Notes:

  • Soft delete (moves to trash)
  • Quota is freed immediately

Using Emotes in Chat

Emotes can be used in chat messages via the inline_emotes field:

{
  "body": "Hello :cool: world!",
  "inline_emotes": [
    {
      "shortcode": "cool",
      "asset_id": 111222333,
      "start_index": 6,
      "end_index": 12
    }
  ]
}

The client should replace :shortcode: patterns with the emote image when rendering.

Uploading Avatars and Emotes

Use the Uploads API:

Profile Picture:

{
  "upload_type": "profile_pic",
  "filename": "avatar.png",
  "content_type": "image/png",
  "size_bytes": 524288,
  "crop_x": 0,
  "crop_y": 0,
  "crop_w": 512,
  "crop_h": 512
}

Emote:

{
  "upload_type": "emote",
  "filename": "reaction.gif",
  "content_type": "image/gif",
  "size_bytes": 102400,
  "shortcode": "reaction"
}
-- ---