← Files Maeve SocialARCHIVED FILE
skills/maeve-social-scheduler/references/content-payloads.md
12.1 KB · Oct 5, 2026 · 18:27 UTC
# Content payloads
Curated from the `maeve-cli` payload schemas. The CLI validates payloads strictly; unknown fields are rejected.
## Contents
- General Rules
- Content Create
- Thread Content
- Schedule Existing Content
- Immediate Publish
- Media
- Approvals
- Client Reviews
- Inbox
- Grid Planner
- Analytics Report
For platform-specific models and clearing behavior, read [Platform content](platform-content.md).
## General rules
- Use UUID strings for workspace, integration, content, media, approver, batch, folder, label, pillar, format, campaign, and campaign phase IDs.
- Grid planner IDs must be UUIDv4 strings.
- Use ISO 8601 timestamps with explicit timezone for scheduling, for example `2026-05-01T10:00:00+10:00` or `2026-05-01T00:00:00Z`.
- Upload local media through Maeve first, then attach it with `contentMedia[].mediaId`.
- Base content create/update targets one `integrationId` and one integration-scoped content row. Multi-platform composition should fan out to separate grouped rows.
- For drafts, omit `intent` or include `intent: "draft"`.
- `content:update` uses the create-content shape except `intent` and `scheduledAt`, and at least one field must be present. Use scheduling or revert-to-draft commands to change publication time.
## Content create
Minimal draft:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"captions": {
"canonical": "Launch post copy"
},
"intent": "draft"
}
```
Scheduled create payload, only when the user provided an explicit date/time/timezone. `scheduledAt` is only allowed when `intent` is `schedule`:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"captions": {
"canonical": "Launch post copy"
},
"contentMedia": [
{
"mediaId": "00000000-0000-4000-8000-000000000002"
}
],
"scheduledAt": "2026-05-01T10:00:00+10:00",
"postType": "post",
"intent": "schedule"
}
```
Platform-aware payload with taxonomy:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"internalTitle": "Launch planning card",
"publishTitle": "Launch title",
"captions": {
"canonical": "Launch post copy"
},
"contentMedia": [
{
"mediaId": "00000000-0000-4000-8000-000000000002",
"order": 0,
"cover": {
"thumbOffsetMs": 2500
}
}
],
"postType": "reel",
"pillarIds": ["00000000-0000-4000-8000-000000000003"],
"formatIds": ["00000000-0000-4000-8000-000000000004"],
"labelIds": ["00000000-0000-4000-8000-000000000005"],
"campaignId": "00000000-0000-4000-8000-000000000006",
"campaignPhaseId": "00000000-0000-4000-8000-000000000007",
"priority": "medium",
"intent": "draft"
}
```
Supported content fields:
- `integrationId`: required UUID.
- `internalTitle`: optional internal planning title, max 500 characters. Never published.
- `publishTitle`: optional provider-facing title, max 500 characters. Required before scheduling/publishing when capabilities say `requiresTitle`.
- `notes`: optional rich-text HTML, max 100000 characters. Internal - never published. Use to attach planning context, links, or meeting notes to a content item.
- `captions`: optional object with `canonical` publish text and optional platform overrides.
- `contentMedia`: optional uploaded media relationships, max 10 before stricter platform limits.
- `scheduledAt`: optional ISO 8601 with timezone.
- `settings`: optional object for platform fields from capabilities.
- `postType`: optional `post`, `reel`, `story`, `thread`, or `poll` (LinkedIn only; requires the top-level `poll` object).
- `poll`: LinkedIn poll content, only with `postType: "poll"`. Question up to 140 characters, 2 to 4 options up to 30 characters each, `duration` of `ONE_DAY`, `THREE_DAYS`, `SEVEN_DAYS`, or `FOURTEEN_DAYS`, `voteSelectionType: "SINGLE_VOTE"`, `isVoterVisibleToAuthor: true`. Polls cannot carry media, documents, or article content.
- `firstComment`, `shareToFeed`: optional publish behavior fields.
- `contentMedia[].crops`, `contentMedia[].userTags`, `contentMedia[].productTags`, `contentMedia[].cover.coverMediaId`, `contentMedia[].cover.thumbOffsetMs`: optional media metadata where platform capabilities allow it.
- `threadMessages`: optional array for thread-style content, max 20 items.
- `pillarIds`, `formatIds`, `labelIds`: optional UUID arrays.
- `campaignId`, `campaignPhaseId`: optional campaign UUIDs; use `null` to clear campaign links on update.
- `assigneeIds`: optional UUID array.
- `priority`: optional `urgent`, `high`, `medium`, or `low`.
- `intent`: optional `draft`, `schedule`, or `publish_now`. Omitted intent defaults to `draft`.
## LinkedIn poll content
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"captions": { "canonical": "Which format should we publish next?" },
"postType": "poll",
"poll": {
"question": "Which format should we publish next?",
"options": [{ "text": "Guide" }, { "text": "Checklist" }],
"duration": "THREE_DAYS",
"voteSelectionType": "SINGLE_VOTE",
"isVoterVisibleToAuthor": true
},
"intent": "draft"
}
```
## Thread content
Use `postType: "thread"` only when the integration capabilities support threads.
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"captions": {
"canonical": "Thread starter"
},
"postType": "thread",
"threadMessages": [
{
"captions": {
"canonical": "Second post in the thread"
}
},
{
"captions": {
"canonical": "Third post with media"
},
"contentMedia": [
{
"mediaId": "00000000-0000-4000-8000-000000000002"
}
]
}
],
"intent": "draft"
}
```
`threadMessages` accepts up to 20 items; each item uses `captions.canonical` and can include `contentMedia`.
## Schedule existing content
CLI command:
```bash
maeve content:schedule --workspace <workspaceId> --id <contentId> --scheduled-at "2026-05-01T10:00:00+10:00"
```
Equivalent payload shape:
```json
{
"scheduledAt": "2026-05-01T10:00:00+10:00"
}
```
## Immediate publish
Publishing uses an existing content ID, not a JSON payload:
```bash
maeve content:publish --workspace <workspaceId> --id <contentId> --yes
```
Confirm first because this is externally visible. The CLI requires `--yes` for publish-now.
## Published caption edit
This edits the provider caption for an already-published Facebook item:
```bash
maeve content:published-caption --workspace <workspaceId> --id <contentId> --json published-caption.json --yes
```
Payload shape:
```json
{
"message": "Updated Facebook caption"
}
```
Confirm first because this changes externally visible provider content. The CLI requires `--yes`.
## Media
Upload files first:
```bash
maeve media:upload ./image.png --workspace <workspaceId>
```
Supported upload extensions:
- Images: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`, `.avif`, max 50 MB.
- Videos: `.mp4`, `.mov`, max 512 MB.
Update media:
```json
{
"filename": "campaign-hero.png",
"altText": "Campaign hero image",
"isFavorite": true,
"folderId": null
}
```
Folders and labels:
```json
{ "name": "Launch assets" }
```
```json
{ "name": "Approved", "color": "#22cc88" }
```
Move folder to root:
```json
{ "parentId": null }
```
Bulk media IDs:
```json
{ "mediaIds": ["00000000-0000-4000-8000-000000000001"] }
```
Bulk label payload:
```json
{
"mediaIds": ["00000000-0000-4000-8000-000000000001"],
"labelIds": ["00000000-0000-4000-8000-000000000002"]
}
```
Media constraints:
- Update payloads must include at least one field.
- Folder/label names are required when creating.
- Label colors must be hex colors.
- Bulk media IDs require 1 to 100 IDs.
- Label ID lists require 1 to 50 IDs.
## Approvals
Internal approval request:
```json
{
"approverIds": ["00000000-0000-4000-8000-000000000001"],
"policy": "any"
}
```
Approval decision:
```json
{
"decision": "reject",
"reason": "Please revise the CTA."
}
```
`decision` is `approve` or `reject`; `reason` is required when rejecting or using `override: true`.
Approval comment:
```json
{
"body": "Looks good to me."
}
```
Comment attachment init:
```json
{
"contentId": "00000000-0000-4000-8000-000000000001",
"audience": "internal",
"filename": "feedback.png",
"contentType": "image/png",
"fileSize": 123456
}
```
Allowed attachment content types: `image/jpeg`, `image/png`, `image/gif`, `image/webp`.
Reaction:
```json
{ "emoji": "thumbs-up" }
```
## Client reviews
Client-only review batch:
```json
{
"contentIds": ["00000000-0000-4000-8000-000000000001"],
"workflowMode": "client",
"client": {
"reviewers": [{ "name": "Client Reviewer", "email": "reviewer@example.com" }],
"policy": "all",
"inviteNote": "Please review when you have a moment.",
"batchLabel": "May launch"
}
}
```
Internal then client review:
```json
{
"contentIds": ["00000000-0000-4000-8000-000000000001"],
"workflowMode": "internal_client",
"internal": {
"approverIds": ["00000000-0000-4000-8000-000000000002"],
"policy": "any"
},
"client": {
"reviewers": [{ "name": "Client Reviewer", "email": "reviewer@example.com" }],
"policy": "all"
}
}
```
Other client-review payloads:
```json
{ "contentId": "00000000-0000-4000-8000-000000000001" }
```
```json
{
"contentId": "00000000-0000-4000-8000-000000000001",
"reason": "Approved outside the portal."
}
```
```json
{
"participantId": "00000000-0000-4000-8000-000000000001",
"email": "reviewer@example.com",
"name": "Updated Name"
}
```
## Inbox
Public reply:
```json
{
"content": "Thanks for reaching out.",
"parentMessageId": "00000000-0000-4000-8000-000000000001"
}
```
Attachment reply:
```json
{
"attachment": {
"type": "image",
"url": "https://cdn.example.com/reply.png"
}
}
```
Internal note:
```json
{ "content": "Follow up with the team before replying." }
```
Moderation:
```json
{ "action": "hide" }
```
Allowed moderation actions: `hide`, `unhide`, `delete`.
Read-all filter:
```json
{
"platform": "instagram",
"status": "open",
"integrationId": "00000000-0000-4000-8000-000000000001",
"messageType": "comment"
}
```
Use `{}` only when the user explicitly wants all matching threads marked read.
## Grid planner
Visual-only item:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"kind": "visual_only",
"mediaIds": ["00000000-0000-4000-8000-000000000002"],
"coverMediaId": "00000000-0000-4000-8000-000000000002",
"note": "Plan this visual",
"settings": { "aspectRatio": 1 }
}
```
Linked content item:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"kind": "linked_post",
"linkedContentId": "00000000-0000-4000-8000-000000000003"
}
```
Update item:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"note": "Updated planning note",
"settings": { "aspectRatio": 1 }
}
```
Reorder requires the complete item order for the integration:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"itemIds": ["00000000-0000-4000-8000-000000000004"]
}
```
Replace media:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"mediaIds": ["00000000-0000-4000-8000-000000000002"]
}
```
Set cover:
```json
{
"integrationId": "00000000-0000-4000-8000-000000000001",
"mediaId": "00000000-0000-4000-8000-000000000005"
}
```
Promote:
```json
{ "integrationId": "00000000-0000-4000-8000-000000000001" }
```
Grid constraints:
- `visual_only` requires `mediaIds`.
- `linked_post` requires `linkedContentId`.
- `mediaIds` and `itemIds` must be unique.
- `coverMediaId` can be a UUIDv4 string or null.
- `settings.aspectRatio` can be null or a number from 0.1 to 10.
- Replace-media accepts 1 to 10 media IDs.
## Analytics report
PDF report payload:
```json
{
"integrationIds": ["00000000-0000-4000-8000-000000000001"],
"days": 30,
"titlePage": {
"enabled": true,
"title": "Monthly report",
"description": "Performance summary"
},
"sections": {
"demographics": true,
"topPosts": true
}
}
```
Rules:
- Include `integrationId` or unique `integrationIds`.
- `integrationIds` can contain 1 to 20 UUIDs.
- `days` is `all` or an integer from 1 to 90.
- `titlePage.title` is max 200 characters.
- `titlePage.description` is max 1000 characters.
SHA-256: abf745ffb611e74d7c546b616f9cfb469491df10838f829dafe628037438ef71