Media

Uploading images and videos to attach to content

Media uploads use a three-step process: create an upload session, upload the file directly to cloud storage, then complete the upload to register the media item in Maeve Social.

Upload flow

1. POST /v1/workspaces/{workspaceId}/media/upload
2. PUT  <presigned uploadUrl>
3. POST /v1/workspaces/{workspaceId}/media/upload/{sessionId}/complete

Step 1: Start an upload

curl -X POST https://api.maevesocial.com/v1/workspaces/WORKSPACE_ID/media/upload \
  -H "Authorization: Bearer $MAEVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "photo.png",
    "contentType": "image/png",
    "fileSize": 102400
  }'
FieldRequiredDescription
filenameYesOriginal filename, max 255 characters
contentTypeYesMIME type
fileSizeYesFile size in bytes

Supported content types

TypeMIMEMax size
JPEGimage/jpeg50 MB
PNGimage/png50 MB
GIFimage/gif50 MB
WebPimage/webp50 MB
AVIFimage/avif50 MB
MP4video/mp4512 MB
QuickTimevideo/quicktime512 MB

Response:

{
  "data": {
    "sessionId": "session-uuid",
    "uploadUrl": "https://storage.example.com/presigned-url...",
    "expiresIn": 3600
  },
  "meta": null
}

Step 2: Upload the file bytes

Upload the file bytes directly to the presigned URL. This request goes to cloud storage, not through the Maeve Social API:

curl -X PUT "PRESIGNED_UPLOAD_URL" \
  -H "Content-Type: image/png" \
  --data-binary @photo.png

Step 3: Complete the upload

curl -X POST https://api.maevesocial.com/v1/workspaces/WORKSPACE_ID/media/upload/SESSION_ID/complete \
  -H "Authorization: Bearer $MAEVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "width": 800,
    "height": 600,
    "folderId": "folder-uuid"
  }'
FieldRequiredDescription
widthNoImage or video width in pixels
heightNoImage or video height in pixels
durationSecondsNoVideo duration in seconds
thumbnailBase64NoBase64-encoded thumbnail image
folderIdNoMedia folder ID

Response:

{
  "data": {
    "id": "media-uuid",
    "url": "https://media.maevesocial.com/...",
    "thumbnailUrl": "https://media.maevesocial.com/.../thumb.jpg",
    "folderId": "folder-uuid",
    "width": 800,
    "height": 600,
    "durationSeconds": null
  },
  "meta": null
}

Attaching media to content

Use the media id in a content item's contentMedia array:

{
  "integrationId": "integration-uuid",
  "intent": "schedule",
  "scheduledAt": "2027-01-01T12:00:00Z",
  "captions": {
    "canonical": "Check out this photo!",
    "overrides": {}
  },
  "contentMedia": [
    {
      "mediaId": "media-uuid",
      "order": 0
    }
  ]
}

You can attach up to 10 media items to one content item.

Listing media

Browse your media library with cursor-based pagination:

curl "https://api.maevesocial.com/v1/workspaces/WORKSPACE_ID/media?type=image&sortBy=createdAt&order=desc&limit=20" \
  -H "Authorization: Bearer $MAEVE_API_KEY"

Query parameters

ParameterDefaultOptions
folderIdnoneFolder UUID
rootOnlynonetrue or false
labelIdsnoneComma-separated media label UUIDs
isUnlabelednonetrue or false
typeallimage, video, gif
searchnoneSearch by filename
isFavoritenonetrue or false
isUsednonetrue or false
isUnusednonetrue or false
stateactiveactive, deleted, all
sortBycreatedAtcreatedAt, filename, fileSize
orderdescasc, desc
limit501-100
cursornoneCursor from the previous response's nextCursor

Response:

{
  "data": [
    {
      "id": "media-uuid",
      "url": "https://media.maevesocial.com/...",
      "thumbnailUrl": "https://media.maevesocial.com/.../thumb.jpg",
      "type": "image/png",
      "filename": "photo.png",
      "altText": null,
      "notes": null,
      "fileSize": 102400,
      "width": 800,
      "height": 600,
      "durationSeconds": null,
      "folderId": "folder-uuid",
      "isFavorite": false,
      "isArchived": false,
      "deletedAt": null,
      "deleteAfter": null,
      "usageCount": 0,
      "labels": [],
      "createdAt": "2026-01-01T00:00:00.000Z",
      "updatedAt": "2026-01-01T00:00:00.000Z"
    }
  ],
  "meta": {
    "limit": 20,
    "hasMore": true,
    "nextCursor": "cursor-string"
  }
}