Content repository

The content repository (or “media repository”) allows users to upload files to their homeserver for later use. For example, files which the user wants to send to a room would be uploaded here, as would an avatar the user wants to use.

Uploads are POSTed to a resource on the user’s local homeserver which returns a MXC URI which can later be used to GET the download. Content is downloaded from the recipient’s local homeserver, which must first transfer the content from the origin homeserver using the same API (unless the origin and destination homeservers are the same).

When serving content, the server SHOULD provide a Content-Security-Policy header. The recommended policy is sandbox; default-src 'none'; script-src 'none'; plugin-types application/pdf; style-src 'unsafe-inline'; object-src 'self';.

Matrix Content (MXC) URIs

Content locations are represented as Matrix Content (MXC) URIs. They look like:

mxc://<server-name>/<media-id>

<server-name> : The name of the homeserver where this content originated, e.g. matrix.org
<media-id> : An opaque ID which identifies the content.

Client behaviour

Clients can upload and download content using the following HTTP APIs.

GET /_matrix/media/v3/config


This endpoint allows clients to retrieve the configuration of the content repository, such as upload limitations. Clients SHOULD use this as a guide when using content repository endpoints. All values are intentionally left optional. Clients SHOULD follow the advice given in the field description when the field is not available.

NOTE: Both clients and server administrators should be aware that proxies between the client and the server may affect the apparent behaviour of content repository APIs, for example, proxies may enforce a lower upload size limit than is advertised by the server on this endpoint.

Rate-limited: Yes
Requires authentication: Yes

Request

No request parameters or request body.


Responses

Status Description
200 The public content repository configuration for the matrix server.
429 This request was rate-limited.

200 response

Name Type Description
m.upload.size integer The maximum size an upload can be in bytes. Clients SHOULD use this as a guide when uploading content. If not listed or null, the size limit should be treated as unknown.
{
  "m.upload.size": 50000000
}

429 response

Error
Name Type Description
errcode string Required: An error code.
error string A human-readable error message.
{
  "errcode": "M_UNKNOWN",
  "error": "An unknown error occurred"
}

GET /_matrix/media/v3/download/{serverName}/{mediaId}


Rate-limited: Yes
Requires authentication: No

Request

Request parameters

path parameters
Name Type Description
mediaId string Required: The media ID from the mxc:// URI (the path component)
serverName string Required: The server name from the mxc:// URI (the authoritory component)
query parameters
Name Type Description
allow_remote boolean Indicates to the server that it should not attempt to fetch the media if it is deemed remote. This is to prevent routing loops where the server contacts itself. Defaults to true if not provided.

Responses

Status Description
200 The content that was previously uploaded.
429 This request was rate-limited.
502 The content is too large for the server to serve.

200 response

429 response

RateLimitError
Name Type Description
errcode string Required: The M_LIMIT_EXCEEDED error code
error string A human-readable error message.
retry_after_ms integer The amount of time in milliseconds the client should wait before trying the request again.
{
  "errcode": "M_LIMIT_EXCEEDED",
  "error": "Too many requests",
  "retry_after_ms": 2000
}

502 response

Error
Name Type Description
errcode string Required: An error code.
error string A human-readable error message.
{
  "errcode": "M_TOO_LARGE",
  "error": "Content is too large to serve"
}

GET /_matrix/media/v3/download/{serverName}/{mediaId}/{fileName}


This will download content from the content repository (same as the previous endpoint) but replace the target file name with the one provided by the caller.

Rate-limited: Yes
Requires authentication: No

Request

Request parameters

path parameters
Name Type Description
fileName string Required: A filename to give in the Content-Disposition header.
mediaId string Required: The media ID from the mxc:// URI (the path component)
serverName string Required: The server name from the mxc:// URI (the authoritory component)
query parameters
Name Type Description
allow_remote boolean Indicates to the server that it should not attempt to fetch the media if it is deemed remote. This is to prevent routing loops where the server contacts itself. Defaults to true if not provided.

Responses

Status Description
200 The content that was previously uploaded.
429 This request was rate-limited.
502 The content is too large for the server to serve.

200 response

429 response

RateLimitError
Name Type Description
errcode string Required: The M_LIMIT_EXCEEDED error code
error string A human-readable error message.
retry_after_ms integer The amount of time in milliseconds the client should wait before trying the request again.
{
  "errcode": "M_LIMIT_EXCEEDED",
  "error": "Too many requests",
  "retry_after_ms": 2000
}

502 response

Error
Name Type Description
errcode string Required: An error code.
error string A human-readable error message.
{
  "errcode": "M_TOO_LARGE",
  "error": "Content is too large to serve"
}

GET /_matrix/media/v3/preview_url


Get information about a URL for the client. Typically this is called when a client sees a URL in a message and wants to render a preview for the user.

Note: Clients should consider avoiding this endpoint for URLs posted in encrypted rooms. Encrypted rooms often contain more sensitive information the users do not want to share with the homeserver, and this can mean that the URLs being shared should also not be shared with the homeserver.

Rate-limited: Yes
Requires authentication: Yes

Request

Request parameters

query parameters
Name Type Description
ts integer The preferred point in time to return a preview for. The server may return a newer version if it does not have the requested version available.
url string Required: The URL to get a preview of.

Responses

Status Description
200 The OpenGraph data for the URL, which may be empty. Some values are replaced with matrix equivalents if they are provided in the response. The differences from the OpenGraph protocol are described here.
429 This request was rate-limited.

200 response

Name Type Description
matrix:image:size integer The byte-size of the image. Omitted if there is no image attached.
og:image string An MXC URI to the image. Omitted if there is no image.
{
  "matrix:image:size": 102400,
  "og:description": "This is a really cool blog post from matrix.org",
  "og:image": "mxc://example.com/ascERGshawAWawugaAcauga",
  "og:image:height": 48,
  "og:image:type": "image/png",
  "og:image:width": 48,
  "og:title": "Matrix Blog Post"
}

429 response

RateLimitError
Name Type Description
errcode string Required: The M_LIMIT_EXCEEDED error code
error string A human-readable error message.
retry_after_ms integer The amount of time in milliseconds the client should wait before trying the request again.
{
  "errcode": "M_LIMIT_EXCEEDED",
  "error": "Too many requests",
  "retry_after_ms": 2000
}

GET /_matrix/media/v3/thumbnail/{serverName}/{mediaId}


Download a thumbnail of content from the content repository. See the Thumbnails section for more information.

Rate-limited: Yes
Requires authentication: No

Request

Request parameters

path parameters
Name Type Description
mediaId string Required: The media ID from the mxc:// URI (the path component)
serverName string Required: The server name from the mxc:// URI (the authoritory component)
query parameters
Name Type Description
allow_remote boolean Indicates to the server that it should not attempt to fetch the media if it is deemed remote. This is to prevent routing loops where the server contacts itself. Defaults to true if not provided.
height integer Required: The desired height of the thumbnail. The actual thumbnail may be larger than the size specified.
method enum The desired resizing method. See the Thumbnails section for more information.

One of: [crop, scale].

width integer Required: The desired width of the thumbnail. The actual thumbnail may be larger than the size specified.

Responses

Status Description
200 A thumbnail of the requested content.
400 The request does not make sense to the server, or the server cannot thumbnail the content. For example, the client requested non-integer dimensions or asked for negatively-sized images.
413 The local content is too large for the server to thumbnail.
429 This request was rate-limited.
502 The remote content is too large for the server to thumbnail.

200 response

400 response

Error
Name Type Description
errcode string Required: An error code.
error string A human-readable error message.
{
  "errcode": "M_UNKNOWN",
  "error": "Cannot generate thumbnails for the requested content"
}

413 response

Error
Name Type Description
errcode string Required: An error code.
error string A human-readable error message.
{
  "errcode": "M_TOO_LARGE",
  "error": "Content is too large to thumbnail"
}

429 response

RateLimitError
Name Type Description
errcode string Required: The M_LIMIT_EXCEEDED error code
error string A human-readable error message.
retry_after_ms integer The amount of time in milliseconds the client should wait before trying the request again.
{
  "errcode": "M_LIMIT_EXCEEDED",
  "error": "Too many requests",
  "retry_after_ms": 2000
}

502 response

Error
Name Type Description
errcode string Required: An error code.
error string A human-readable error message.
{
  "errcode": "M_TOO_LARGE",
  "error": "Content is too large to thumbnail"
}

POST /_matrix/media/v3/upload


Rate-limited: Yes
Requires authentication: Yes

Request

Request parameters

header parameters
Name Type Description
Content-Type string The content type of the file being uploaded
query parameters
Name Type Description
filename string The name of the file being uploaded

Request body

Request body example

"<bytes>"

Responses

Status Description
200 The MXC URI for the uploaded content.
403

The user does not have permission to upload the content. Some reasons for this error include:

  • The server does not permit the file type.
  • The user has reached a quota for uploaded content.
413 The uploaded content is too large for the server.
429 This request was rate-limited.

200 response

Name Type Description
content_uri string Required: The MXC URI to the uploaded content.
{
  "content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw"
}

403 response

Error
Name Type Description
errcode string Required: An error code.
error string A human-readable error message.
{
  "errcode": "M_FORBIDDEN",
  "error": "Cannot upload this content"
}

413 response

Error
Name Type Description
errcode string Required: An error code.
error string A human-readable error message.
{
  "errcode": "M_TOO_LARGE",
  "error": "Cannot upload files larger than 100mb"
}

429 response

RateLimitError
Name Type Description
errcode string Required: The M_LIMIT_EXCEEDED error code
error string A human-readable error message.
retry_after_ms integer The amount of time in milliseconds the client should wait before trying the request again.
{
  "errcode": "M_LIMIT_EXCEEDED",
  "error": "Too many requests",
  "retry_after_ms": 2000
}
Thumbnails

The homeserver SHOULD be able to supply thumbnails for uploaded images and videos. The exact file types which can be thumbnailed are not currently specified - see Issue #1938 for more information.

The thumbnail methods are “crop” and “scale”. “scale” tries to return an image where either the width or the height is smaller than the requested size. The client should then scale and letterbox the image if it needs to fit within a given rectangle. “crop” tries to return an image where the width and height are close to the requested size and the aspect matches the requested size. The client should scale the image if it needs to fit within a given rectangle.

The dimensions given to the thumbnail API are the minimum size the client would prefer. Servers must never return thumbnails smaller than the client’s requested dimensions, unless the content being thumbnailed is smaller than the dimensions. When the content is smaller than the requested dimensions, servers should return the original content rather than thumbnail it.

Servers SHOULD produce thumbnails with the following dimensions and methods:

In summary:

Servers MUST NOT upscale thumbnails under any circumstance. Servers MUST NOT return a smaller thumbnail than requested, unless the original content makes that impossible.

Security considerations

The HTTP GET endpoint does not require any authentication. Knowing the URL of the content is sufficient to retrieve the content, even if the entity isn’t in the room.

MXC URIs are vulnerable to directory traversal attacks such as mxc://127.0.0.1/../../../some_service/etc/passwd. This would cause the target homeserver to try to access and return this file. As such, homeservers MUST sanitise MXC URIs by allowing only alphanumeric (A-Za-z0-9), _ and - characters in the server-name and media-id values. This set of whitelisted characters allows URL-safe base64 encodings specified in RFC 4648. Applying this character whitelist is preferable to blacklisting . and / as there are techniques around blacklisted characters (percent-encoded characters, UTF-8 encoded traversals, etc).

Homeservers have additional content-specific concerns: