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';.
[Added in v1.4]
The server SHOULD additionally provide
Cross-Origin-Resource-Policy: cross-origin when serving content to allow
(web) clients to access restricted APIs such as SharedArrayBuffer when
interacting with the media repository.
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.
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
{
"errcode": "M_UNKNOWN",
"error": "An unknown error occurred"
}
| 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
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
502 response
{
"errcode": "M_TOO_LARGE",
"error": "Content is too large to serve"
}
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
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
502 response
{
"errcode": "M_TOO_LARGE",
"error": "Content is too large to serve"
}
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
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
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
{
"errcode": "M_UNKNOWN",
"error": "Cannot generate thumbnails for the requested content"
}
413 response
{
"errcode": "M_TOO_LARGE",
"error": "Content is too large to thumbnail"
}
429 response
{
"errcode": "M_LIMIT_EXCEEDED",
"error": "Too many requests",
"retry_after_ms": 2000
}
502 response
{
"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
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
{
"errcode": "M_FORBIDDEN",
"error": "Cannot upload this content"
}
413 response
{
"errcode": "M_TOO_LARGE",
"error": "Cannot upload files larger than 100mb"
}
429 response
{
"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:
- 32x32, crop
- 96x96, crop
- 320x240, scale
- 640x480, scale
- 800x600, scale
In summary:
- “scale” maintains the original aspect ratio of the image
- “crop” provides an image in the aspect ratio of the sizes given in
the request
- The server will return an image larger than or equal to the
dimensions requested where possible.
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:
- Clients may try to upload very large files. Homeservers should not
store files that are too large and should not serve them to clients,
returning a HTTP 413 error with the
M_TOO_LARGE code.
- Clients may try to upload very large images. Homeservers should not
attempt to generate thumbnails for images that are too large,
returning a HTTP 413 error with the
M_TOO_LARGE code.
- Remote homeservers may host very large files or images. Homeservers
should not proxy or thumbnail large files or images from remote
homeservers, returning a HTTP 502 error with the
M_TOO_LARGE code.
- Clients may try to upload a large number of files. Homeservers
should limit the number and total size of media that can be uploaded
by clients, returning a HTTP 403 error with the
M_FORBIDDEN code.
- Clients may try to access a large number of remote files through a
homeserver. Homeservers should restrict the number and size of
remote files that it caches.
- Clients or remote homeservers may try to upload malicious files
targeting vulnerabilities in either the homeserver thumbnailing or
the client decoders.