Aveiro Documentation
Getting Started
What Is Aveiro?
Create Your Account
Create Your First Site
Dashboard Tour
Key Concepts
Members and Permissions
API Tokens
Aveiro MCP server
Account security — sessions and connected AI apps
Organization
Affiliate Program
Sites
Sites Overview
Choosing a Template
Managing Sites
Preview and Live URLs
Build from your content
Social
Social Publishing Overview
Connecting Social Accounts
Social Approval Workflow
Social Agents and API
Audience
Audience Overview
Campaigns
Automation
Segments
Deliverability
Sending Domains
Embed Forms
Subscribers
Audience Agents and API
Messaging
Messaging Overview
Visitor Support Chat
Inbox
Analytics
Analytics Overview
Events
Live Visitors
Page Analytics
Editor
Editor Overview
Media Library
Pages
Pages Overview
File Tree and Collections
Creating and Organizing Pages
Page Settings
Publishing Pages
Version History
Ai
AI Overview
Chat and Suggestions
Working with AI Changes
Translations
Translations Overview
Layout
Layout Overview
Site Layouts
Collection Layouts
Header, Footer, and Sidebars
Ad Placements
Components
Components Overview
Adding and Editing Components
Component Categories
Writing with MDX
Page Sections
Editing
Keyboard Shortcuts
Preview, Visual, and Source
Styles
Styles Overview
Block Styles
Site Theme and Branding
Settings
Visitor Login
Analytics and Privacy
Custom Domains
Settings Overview
Publishing Settings vs Content
SEO and Social Sharing
Site Name and URL
Visitor Assistant
Site Ad Settings
Integrations
Integrations Overview
Fourthwall Integration
Studio
Studio Overview
Frametic Studio
Monetization
Monetization Overview
Products
Merchant of Record
Ads
Ads Overview
Managing Ad Inventory
TrademarkTrademark
Ctrl k
Search…
Sign up
Aveiro Documentation
Getting Started
What Is Aveiro?
Create Your Account
Create Your First Site
Dashboard Tour
Key Concepts
Members and Permissions
API Tokens
Aveiro MCP server
Account security — sessions and connected AI apps
Organization
Affiliate Program
Sites
Sites Overview
Choosing a Template
Managing Sites
Preview and Live URLs
Build from your content
Social
Social Publishing Overview
Connecting Social Accounts
Social Approval Workflow
Social Agents and API
Audience
Audience Overview
Campaigns
Automation
Segments
Deliverability
Sending Domains
Embed Forms
Subscribers
Audience Agents and API
Messaging
Messaging Overview
Visitor Support Chat
Inbox
Analytics
Analytics Overview
Events
Live Visitors
Page Analytics
Editor
Editor Overview
Media Library
Pages
Pages Overview
File Tree and Collections
Creating and Organizing Pages
Page Settings
Publishing Pages
Version History
Ai
AI Overview
Chat and Suggestions
Working with AI Changes
Translations
Translations Overview
Layout
Layout Overview
Site Layouts
Collection Layouts
Header, Footer, and Sidebars
Ad Placements
Components
Components Overview
Adding and Editing Components
Component Categories
Writing with MDX
Page Sections
Editing
Keyboard Shortcuts
Preview, Visual, and Source
Styles
Styles Overview
Block Styles
Site Theme and Branding
Settings
Visitor Login
Analytics and Privacy
Custom Domains
Settings Overview
Publishing Settings vs Content
SEO and Social Sharing
Site Name and URL
Visitor Assistant
Site Ad Settings
Integrations
Integrations Overview
Fourthwall Integration
Studio
Studio Overview
Frametic Studio
Monetization
Monetization Overview
Products
Merchant of Record
Ads
Ads Overview
Managing Ad Inventory
TrademarkTrademark
AveiroBlogContact
© Aveiro. All rights reserved.
Built with Aveiro

Social Agents and API

Let AI agents draft social posts via /api/v1/social and aveiro_social_* MCP tools. Requires social:write. Approving needs the opt-in social:approve scope and your confirmation of each post.
Updated 17 days ago
Social Approval Workflow
In short
Grant social:write on an API token or MCP OAuth connection. Agents list accounts, create and revise drafts, generate media, and read rejection feedback. If you also switch on the opt-in social:approve scope, an agent can approve or reject one post at a time after you confirm it in the conversation. Post now stays in the dashboard.

What agents can and cannot do

Action
Agent (API / MCP)
Human (dashboard)
List connected accountsYesYes
Create and revise drafts
Yes — draft, pending_approval, rejected only
Yes
Generate or register mediaYesYes
Read feedback timelineYesYes
Approve or reject one post
Only with the opt-in social:approve scope, after you confirm that post
Yes
Post nowNo — dashboard onlyYes
Publish autonomouslyNo — every post needs an approvalNo without approval
This split is intentional. Social posts go to public profiles, so approval is never part of a default token or AI app connection. social:approve is opt-in: you switch it on per token, or tick Allow approving and rejecting social posts when you connect an AI app. With it, the agent is told to show you the final post — captions, targets, media, first comment, and publish time — and wait for your explicit yes for that specific post. Each approval is pinned to the version you saw: if the post changes, the call fails and the agent has to show it again. Aveiro cannot see your conversation, though, so it cannot check that you confirmed. Only allow approval for an app or tool you trust.

Token setup

  • Enable Social publishing under Organization → Features
  • Open Organization → API tokens → Create token
  • Add the social:write scope (requires Audience manage capability)
  • Optional: switch on to let the token approve or reject posts after you confirm each one (also requires ; it turns on too)
social:approve
Audience manage
social:write
  • Copy the av_live_… secret — shown once
  • For MCP in ChatGPT, Cursor, or Claude, connect via the hosted MCP server at https://www.aveiro.app/api/mcp/mcp. OAuth connections include social:write. On the consent screen, tick Allow approving and rejecting social posts to add social:approve — it is off by default. An app you connected before cannot approve: disconnect it under Account settings → Security → Connected AI apps, connect it again, and tick the box.
    Default content tokens (sites:read, content:read, content:write) do not include social access — add social:write explicitly.
    See API tokens for the full scope list.

    REST API

    All routes live under /api/v1/social on your platform host. Full reference: Social API overview.
    Method
    Route
    Purpose
    GET/api/v1/social/accounts
    Connected Instagram/Threads accounts and IDs for targets
    GET/api/v1/social/posts
    List posts — filter by status (e.g. rejected, pending_approval)
    POST/api/v1/social/posts
    Create a draft (source=mcp); optional submitForReview
    GET/api/v1/social/posts/{postId}One post with full event timeline
    PATCH/api/v1/social/posts/{postId}Revise draft, pending, or rejected post
    POST/api/v1/social/posts/{postId}/approve
    Approve one confirmed post, pinned to its revision; it publishes at its scheduled time (social:approve)
    POST/api/v1/social/posts/{postId}/reject
    Reject one post with feedback, or undo an approval before it publishes (social:approve)
    GET/api/v1/social/media
    Social media library (registered and generated assets)
    GET/api/v1/social/org-media
    Browse org media storage (dashboard uploads — not yet in the social library)
    POST/api/v1/social/media
    Register a public URL into the social library
    POST/api/v1/social/media/upload
    Get a direct-upload target for a local image or video file
    POST/api/v1/social/media/generate
    AI image generation — up to 4 aspectRatios per call (plan + credits per ratio)
    Send Authorization: Bearer av_live_… on every request.

    Typical agent loop

    • GET /api/v1/social/accounts — pick target account IDs
    • GET /api/v1/social/org-media (optional) — find an existing dashboard upload, then POST /api/v1/social/media to register its URL
    • POST /api/v1/social/media/generate or POST /api/v1/social/media — attach media
    • POST /api/v1/social/posts with targets, content, platformOverrides, proposedScheduleAt, and a note explaining the draft
    • Human approves in Dashboard → Social — or, with social:approve, the agent shows the post, the human confirms it in the conversation, and the agent calls POST /api/v1/social/posts/{id}/approve with the post's revision
    • If rejected, GET /api/v1/social/posts/{id} — read events, then PATCH with fixes and submitForReview: true
    Caption limits enforced at validation: Instagram 2,200, Threads 500, X 280 characters.

    LinkedIn PDF carousels

    A LinkedIn carousel is a document post — one multi-page PDF the feed paginates into swipeable slides. Agents do not generate or upload that PDF: attach the slides as ordinary image assets in slide order and set postType: "document" on the LinkedIn target. Aveiro composes the document from those slides at publish time.
    platformTitles.linkedin (max 400 chars) is the headline above the slides; without one, the first line of the LinkedIn caption is used. The caption and first comment publish as on a feed post, the 10-image cap does not apply (the slides become pages), a video cannot be a slide, and every other target still gets the same slides as images. Generate the deck at one aspect ratio — 1:1 or 4:5 read best, and a slide of a different shape is letterboxed rather than cropped.

    Multi-aspect generation and per-platform crops

    POST /api/v1/social/media/generate accepts aspectRatios — an array of up to four supported ratios (1:1, 4:5, 5:4, 3:4, 4:3, 2:3, 3:2, 9:16, 16:9). Default is ["16:9"]. Each ratio is generated independently with the same prompt and billed as one AI image generation.
    The response is { assets, failures } — partial success is normal when one ratio fails quota or provider limits.
    aveiro_social_generate_media accepts the same aspect_ratios parameter (max four).
    Assign each returned asset to a platform. An assignment's platform field is what marks an asset as a crop: assets attached to a platform are that platform's own set and replace the generic one for it.
    Assets left generic (platform: null) are the post's carousel, and every one of them publishes, in sortOrder. So attaching three ratios of the same picture without a platform no longer produces one auto-picked crop — it produces a three-slide carousel of the same picture on every target.
    This used to be an auto-pick by aspect ratio. It was removed because it could not tell one visual in three crops apart from three different pictures, and it silently truncated the second case.
    Full field reference: Social media API.

    Org media storage vs social library

    Aveiro keeps two media buckets:
    • Org media storage — files uploaded through any dashboard dialog (brand assets, screenshots, AI images saved to the org library). Browse with GET /api/v1/social/org-media.
    • Social media library — assets registered or generated for social posts (GET /api/v1/social/media). Only these IDs attach to drafts.
    To reuse an org upload on a social post, register its public URL with POST /api/v1/social/media (or aveiro_social_register_media). Registration is idempotent per URL. Use mediaType: "video" for Reels — the AI generator produces images only.

    Direct uploads from agents

    When the file only exists on the agent's side — an image generated on the caller's own AI plan, a video rendered locally — POST /api/v1/social/media/upload (or aveiro_social_prepare_upload) returns a short-lived upload target. The agent PUTs the raw bytes to it over plain HTTPS, then registers the returned publicUrl as usual. Images (JPEG/PNG/WebP/GIF, max 10MB) land in org image storage; videos (MP4/WebM/MOV, max 200MB) land directly on the video CDN, so no host: true is needed on the register call.
    This flow needs a client that can make HTTP requests (shell or code execution, e.g. Claude Code or Cursor). Chat-only MCP clients can't push local bytes — they keep using register-by-URL. See the Social media API for the exact request/response shapes.

    MCP tools

    The Aveiro MCP server exposes thin wrappers around the same routes:
    Tool
    REST equivalent
    aveiro_social_list_accountsGET /api/v1/social/accounts
    aveiro_social_list_postsGET /api/v1/social/posts
    aveiro_social_get_postGET /api/v1/social/posts/{id}
    aveiro_social_create_draftPOST /api/v1/social/posts
    aveiro_social_update_draftPATCH /api/v1/social/posts/{id}
    aveiro_social_approve_post
    POST /api/v1/social/posts/{id}/approve (social:approve)
    aveiro_social_reject_post
    POST /api/v1/social/posts/{id}/reject (social:approve)
    aveiro_social_list_mediaGET /api/v1/social/media
    aveiro_social_list_org_mediaGET /api/v1/social/org-media
    aveiro_social_register_mediaPOST /api/v1/social/media
    aveiro_social_prepare_uploadPOST /api/v1/social/media/upload
    aveiro_social_generate_mediaPOST /api/v1/social/media/generate
    Tools are available on the hosted MCP server and the stdio server in mcp/aveiro. See the Aveiro MCP README in the repo for local setup.

    Proposed vs confirmed schedule

    Agents set proposedScheduleAt on create or update. The dashboard row shows this as a proposed time. It never triggers publish.
    When a human approves — by clicking Approve in the dashboard, where the datetime picker sets the confirmed scheduled_at, or by confirming the post in an AI app allowed to approve — the post is scheduled. An AI app approval uses the post's own schedule, else its proposed time, unless you chose a different time in the conversation. Only approved, scheduled posts reach Chirio via the dispatcher.
    A proposal is not validated when the agent writes it, but it is when a human approves: approval requires a confirmed time in the future. A proposal that has since gone stale is refused at that point, and the reviewer picks a new time — it never becomes an instant publish, in the dashboard or through an AI app.

    Related

    • Social overview
    • Approval workflow
    • API tokens
    • Social API reference
    • Social post review API
    {
      "content": "Five things nobody tells you about RLS 👇",
      "platformTitles": { "linkedin": "Five things nobody tells you about RLS" },
      "targets": [{ "platform": "linkedin", "accountId": "…", "postType": "document" }],
      "mediaAssignments": [
        { "assetId": "…", "platform": null, "sortOrder": 0 },
        { "assetId": "…", "platform": null, "sortOrder": 1 }
      ]
    }