or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

accounts.mdauthentication.mdconversations.mdfilters.mdindex.mdinstance.mdlists.mdmedia.mdnotifications.mdpolls.mdreports.mdsearch.mdstatuses.mdstreaming.mdtags.mdtimelines.mdtypes.md
tile.json

media.mddocs/

Media Attachments

Complete media upload and attachment management.

Types

Attachment

type Attachment struct {
    ID          ID
    Type        string
    URL         string
    RemoteURL   string
    PreviewURL  string
    TextURL     string
    Description string
    BlurHash    string
    Meta        AttachmentMeta
}

Attachment holds information for a media attachment.

Fields:

  • ID - Unique attachment identifier
  • Type - Media type ("image", "video", "gifv", "audio", "unknown")
  • URL - URL of the media file
  • RemoteURL - Remote URL if media is from another instance
  • PreviewURL - URL of the preview/thumbnail
  • TextURL - Deprecated text URL
  • Description - Alt text description for accessibility
  • BlurHash - BlurHash string for placeholder generation
  • Meta - Metadata about dimensions and focus

AttachmentMeta

type AttachmentMeta struct {
    Original AttachmentSize
    Small    AttachmentSize
    Focus    AttachmentFocus
}

AttachmentMeta holds metadata for attachment dimensions and focus point.

Fields:

  • Original - Original file dimensions
  • Small - Thumbnail/preview dimensions
  • Focus - Focal point for cropping

AttachmentSize

type AttachmentSize struct {
    Width  int64
    Height int64
    Size   string
    Aspect float64
}

AttachmentSize holds dimension information for an attachment.

Fields:

  • Width - Width in pixels
  • Height - Height in pixels
  • Size - Size string (e.g., "1920x1080")
  • Aspect - Aspect ratio (width/height)

AttachmentFocus

type AttachmentFocus struct {
    X float64
    Y float64
}

AttachmentFocus holds focal point coordinates for smart cropping.

Fields:

  • X - Horizontal focal point (-1.0 to 1.0, 0 is center)
  • Y - Vertical focal point (-1.0 to 1.0, 0 is center)

Media

type Media struct {
    File        io.Reader
    Thumbnail   io.Reader
    Description string
    Focus       string
}

Media is a struct for uploading media with additional metadata.

Fields:

  • File - Media file reader
  • Thumbnail - Optional custom thumbnail reader
  • Description - Alt text description for accessibility
  • Focus - Focal point string (e.g., "0.5,-0.3")

Upload Methods

UploadMedia { .api }

func (c *Client) UploadMedia(ctx context.Context, file string) (*Attachment, error)

Uploads media from a file path.

Parameters:

  • ctx - Context for cancellation/timeout
  • file - Path to file to upload

Returns: Attachment with media ID or error

Example:

attachment, err := client.UploadMedia(ctx, "/path/to/image.jpg")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Uploaded media ID: %s\n", attachment.ID)

// Use in status
toot := &mastodon.Toot{
    Status:   "Check out this image!",
    MediaIDs: []mastodon.ID{attachment.ID},
}
status, err := client.PostStatus(ctx, toot)

UploadMediaFromBytes { .api }

func (c *Client) UploadMediaFromBytes(ctx context.Context, b []byte) (*Attachment, error)

Uploads media from a byte slice.

Parameters:

  • ctx - Context for cancellation/timeout
  • b - Byte slice containing media data

Returns: Attachment with media ID or error

Example:

imageData, err := os.ReadFile("image.png")
if err != nil {
    log.Fatal(err)
}

attachment, err := client.UploadMediaFromBytes(ctx, imageData)
if err != nil {
    log.Fatal(err)
}

UploadMediaFromReader { .api }

func (c *Client) UploadMediaFromReader(ctx context.Context, reader io.Reader) (*Attachment, error)

Uploads media from an io.Reader.

Parameters:

  • ctx - Context for cancellation/timeout
  • reader - Reader providing media data

Returns: Attachment with media ID or error

Example:

file, err := os.Open("photo.jpg")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

attachment, err := client.UploadMediaFromReader(ctx, file)
if err != nil {
    log.Fatal(err)
}

UploadMediaFromMedia { .api }

func (c *Client) UploadMediaFromMedia(ctx context.Context, media *Media) (*Attachment, error)

Uploads media from a Media struct with additional metadata.

Parameters:

  • ctx - Context for cancellation/timeout
  • media - Media struct with file and metadata

Returns: Attachment with media ID or error

Example:

file, err := os.Open("image.jpg")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

media := &mastodon.Media{
    File:        file,
    Description: "A beautiful sunset over the ocean",
    Focus:       "0.5,-0.3", // Focus slightly above center
}

attachment, err := client.UploadMediaFromMedia(ctx, media)
if err != nil {
    log.Fatal(err)
}

// Use in status
toot := &mastodon.Toot{
    Status:   "Sunset photo",
    MediaIDs: []mastodon.ID{attachment.ID},
}
status, err := client.PostStatus(ctx, toot)

Usage Examples

Example: Upload Multiple Images

imagePaths := []string{
    "/path/to/image1.jpg",
    "/path/to/image2.jpg",
    "/path/to/image3.jpg",
}

var mediaIDs []mastodon.ID
for _, path := range imagePaths {
    attachment, err := client.UploadMedia(ctx, path)
    if err != nil {
        log.Fatal(err)
    }
    mediaIDs = append(mediaIDs, attachment.ID)
}

// Post with all images
toot := &mastodon.Toot{
    Status:   "Photo album!",
    MediaIDs: mediaIDs,
}
status, err := client.PostStatus(ctx, toot)

Example: Upload with Alt Text

file, err := os.Open("chart.png")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

media := &mastodon.Media{
    File:        file,
    Description: "Bar chart showing quarterly sales increase of 25%",
}

attachment, err := client.UploadMediaFromMedia(ctx, media)
if err != nil {
    log.Fatal(err)
}

toot := &mastodon.Toot{
    Status:   "Q4 results are in!",
    MediaIDs: []mastodon.ID{attachment.ID},
}
status, err := client.PostStatus(ctx, toot)

Example: Upload from HTTP Response

resp, err := http.Get("https://example.com/image.jpg")
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

attachment, err := client.UploadMediaFromReader(ctx, resp.Body)
if err != nil {
    log.Fatal(err)
}

Example: Upload with Custom Thumbnail

videoFile, err := os.Open("video.mp4")
if err != nil {
    log.Fatal(err)
}
defer videoFile.Close()

thumbnailFile, err := os.Open("thumbnail.jpg")
if err != nil {
    log.Fatal(err)
}
defer thumbnailFile.Close()

media := &mastodon.Media{
    File:        videoFile,
    Thumbnail:   thumbnailFile,
    Description: "Tutorial video: Getting started with Go",
}

attachment, err := client.UploadMediaFromMedia(ctx, media)
if err != nil {
    log.Fatal(err)
}

Example: Upload with Focus Point

The focus point determines where the image is cropped in previews:

file, err := os.Open("portrait.jpg")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

// Focus on subject's face (slightly right, upper third)
media := &mastodon.Media{
    File:        file,
    Description: "Portrait photo",
    Focus:       "0.2,0.3", // X: 20% right of center, Y: 30% above center
}

attachment, err := client.UploadMediaFromMedia(ctx, media)
if err != nil {
    log.Fatal(err)
}

Focus coordinates range from -1.0 to 1.0 on both axes:

  • X: -1.0 (left edge) to 1.0 (right edge), 0 is center
  • Y: -1.0 (bottom edge) to 1.0 (top edge), 0 is center

Example: Upload Generated Image

import (
    "bytes"
    "image"
    "image/png"
)

// Generate an image
img := image.NewRGBA(image.Rect(0, 0, 800, 600))
// ... draw on image ...

// Encode to PNG
var buf bytes.Buffer
err := png.Encode(&buf, img)
if err != nil {
    log.Fatal(err)
}

// Upload
attachment, err := client.UploadMediaFromReader(ctx, &buf)
if err != nil {
    log.Fatal(err)
}

Supported Media Types

Images

  • JPEG (.jpg, .jpeg)
  • PNG (.png)
  • GIF (.gif) - Static or animated
  • WebP (.webp)

Videos

  • MP4 (.mp4)
  • WebM (.webm)
  • MOV (.mov)

Audio

  • MP3 (.mp3)
  • OGG (.ogg)
  • WAV (.wav)
  • FLAC (.flac)
  • OPUS (.opus)
  • AAC (.aac)
  • M4A (.m4a)
  • 3GP (.3gp)

Limits and Constraints

Typical Mastodon instance limits (may vary by instance):

  • Image files: Max 16MB (8MP pixels for JPEG/PNG)
  • Video files: Max 99MB or 40MB (varies by instance)
  • Audio files: Max 99MB or 40MB (varies by instance)
  • Attachments per status: Up to 4 media files
  • Description length: 1500 characters

Check instance configuration for specific limits:

instance, err := client.GetInstance(ctx)
if err != nil {
    log.Fatal(err)
}

// Check media attachment limits
if config := instance.Configuration; config != nil {
    if mediaConfig, ok := config.MediaAttachments["image_size_limit"]; ok {
        fmt.Printf("Image size limit: %v\n", mediaConfig)
    }
}

Best Practices

1. Always Provide Alt Text

Alt text is essential for accessibility:

media := &mastodon.Media{
    File:        file,
    Description: "Detailed description of image content",
}

2. Set Appropriate Focus Points

For portraits and important subjects, set focus points to ensure proper cropping:

media := &mastodon.Media{
    File:  file,
    Focus: "0.2,0.4", // Focus on subject's face
}

3. Handle Upload Errors

Media uploads can fail due to size limits or format issues:

attachment, err := client.UploadMedia(ctx, path)
if err != nil {
    if apiErr, ok := err.(*mastodon.APIError); ok {
        if apiErr.StatusCode == 413 {
            log.Printf("File too large")
        } else if apiErr.StatusCode == 422 {
            log.Printf("Invalid file format")
        }
    }
    return err
}

4. Optimize Before Upload

Consider optimizing media before upload to reduce file size:

// Resize image if too large
if fileInfo.Size() > 8*1024*1024 { // 8MB
    // Resize image...
}

5. Reuse Attachment IDs

Attachment IDs can be reused within a short time window (typically 24 hours):

// Upload once
attachment, err := client.UploadMedia(ctx, "image.jpg")
if err != nil {
    log.Fatal(err)
}

// Use in multiple toots (if allowed by instance)
toot1 := &mastodon.Toot{
    Status:   "First post with image",
    MediaIDs: []mastodon.ID{attachment.ID},
}

// Note: Not all instances allow reusing media IDs

Error Handling

attachment, err := client.UploadMedia(ctx, path)
if err != nil {
    if apiErr, ok := err.(*mastodon.APIError); ok {
        switch apiErr.StatusCode {
        case 413:
            log.Fatal("File too large")
        case 422:
            log.Fatal("Invalid file format or corrupted file")
        case 500:
            log.Fatal("Server error processing media")
        default:
            log.Fatalf("Upload failed: %v", apiErr)
        }
    }
    log.Fatal(err)
}

Related Types

See also:

  • Statuses - For using media in statuses
  • Types - For ID and other common types