POST the bytes and the response gives you an asset ID.
Pass that ID to a GraphQL mutation to attach the asset to a post or article, a chat message, a member’s profile, an event, or a Space or Network image slot. See Attaching uploaded assets for post and comment body restrictions.
Video and audio go through the
createUploadSession mutation, not this endpoint. That path uploads in chunks and puts the file through transcoding, so the result plays in the product. This endpoint stores a single file in one request.Endpoint
{network_id} segment takes either the Network’s numeric ID (for example 12345) or its subdomain slug (for example my-community for my-community.mn.co), the same two forms the GraphQL endpoint accepts.
Send a file as multipart/form-data. A base64 or source_url upload carries no binary, so it can be sent as ordinary form fields instead.
Authentication and scopes
Authenticate the same way you authenticate a GraphQL request: pass an OAuth access token or an Admin API key as a Bearer token.write:assets. A Host credential, such as an Admin API key, can carry host:write:network_assets instead. Either one satisfies the endpoint, and a credential holding neither receives a 403.
See the Authentication Guide for the OAuth flows and OAuth Applications — Scopes for the full scope catalog.
Request fields
Every upload names its source with exactly one offile, base64, or source_url. Everything else is optional.
Send
metadata either as nested form fields (metadata[is_main_image]=true) or as a JSON object string (metadata={"is_main_image":true}). Both keys are declarations, so false and omitting the key mean the same thing, and keys other than the two above are dropped.
Asset styles
asset_style tells Mighty what the asset is for, which decides how it is stored and processed. Pick the style that matches where the asset will end up.
The destination slot determines the final style. A detached asset can be restyled and attached in place; reusing an asset already attached to other content can create a copy.For
createEvent and updateEvent, thumbnailId cannot name an asset styled cinema_header, and thumbnailId and headerId must name different assets. Pass headerId alone to use the header on the event card when the event has no separate thumbnail.asset_style outside the table is rejected with a 400. So are the video and audio styles, which return a 400 pointing you at createUploadSession.
Limits and validation
Size. Afile or base64 upload larger than 25 MB is rejected with a 413 before anything is stored. A source_url has no size until it is fetched, so a fetched file over 25 MB is rejected with a 400 and the message Validation failed: This file must be 25MB or smaller.
Content types. Uploads are checked against an allowlist of common image types (JPEG, PNG, GIF, WebP, AVIF, HEIC, HEIF, TIFF, BMP), audio types (MP3, M4A, WAV, FLAC, AIFF), video types (MP4, MOV), and document types (PDF, plain text, CSV, Word, Excel, PowerPoint, Pages). SVG, HTML, and script or executable files are refused whatever content type they declare, because they can carry executable content.
Source URLs. A source_url has to use http or https. Loopback addresses are rejected with Invalid URL, and private or internal addresses are refused by the server’s outbound request filter, so the URL has to be reachable from the public internet. The fetch gives up after 5 seconds to connect and 5 seconds to read. A failed download returns 400 with validation details that can include missing-file, missing-content-type, and download errors. An empty stored file can return This file is empty or failed to upload. Please try again.
Main image. For file and base64 uploads, metadata[is_main_image] is kept only when the declared content type or filename extension identifies JPEG, PNG, GIF, WebP, AVIF, HEIC, or HEIF. Either signal is enough. Other formats, including accepted image uploads such as TIFF and BMP, lose the key without failing the request. A source_url upload skips this check and retains the declaration regardless of the fetched file’s type.
Response
A successful upload returns201 with the stored asset.
Mapping from the Admin API
If you are moving an upload call over from the Admin API, itsAssetResponse fields land here as follows.
Errors
Endpoint errors return a JSON body of the shape{ "error": "..." }. The bot-protection challenge described above is an HTML response.
Attaching uploaded assets
For a post or article, pass the upload response’sid in assetIds on createPost or updatePost. Their body accepts plain text and formatting HTML. Tags such as <img>, <a>, and <iframe> are rejected, even when they include an asset ID.
On updatePost, assetIds replaces the attachment list. Include all IDs you want to keep, or omit assetIds to leave attachments unchanged.
Comments have a separate body format: createComment and updateComment sanitize the HTML you send and remove iframes. Neither mutation exposes an assetIds argument.
Examples
Upload a file, mark it as the content’s main image, and record its aspect ratio:Next steps
Mighty API
Attach the asset with a GraphQL mutation.
Authentication
Get a token that carries an asset write scope.