Skip to main content
Glama

Bulk Create Posts

aidelly_bulk_create_posts

Create up to 50 scheduled posts in one call. Each item takes the same shape as aidelly_create_post. Returns HTTP 201 when every item was accepted and 207 when some failed, with a per-item results array carrying index, status, and either the created post or an error. Acceptance is not delivery; aidelly_get_post reports delivery for each created id. Rate limit is charged per post, not per request, so a 20-post batch costs 20 write units: it saves round trips, not quota. The whole batch is rejected before anything is written if it would exceed the daily scheduling limit. LinkedIn document posts attach one PDF (≤100 MB, ≤300 pages) as media[].type = "document"; documents are rejected on every other platform. Retry-safe: a repeat call with the same idempotency_key returns the original result.

Input Schema

NameRequiredDescriptionDefault
bodyNoOptional body override for endpoints with sparse parameter schemas.
postsYesPosts to create. Max 50 per request.
queryNoOptional query overrides for endpoints with sparse parameter schemas.
brand_idNo
workspace_idNoWorkspace to operate in: the `id` of a workspace returned by aidelly_list_workspaces. Optional for read operations; required when creating content.
idempotency_keyYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / posts / items / properties / content / properties / media / items / properties / title
      Added value: +{
      +  "description": "Title LinkedIn shows on a document (PDF carousel) post, trimmed, up to 200 characters. Without one, LinkedIn shows the uploaded file name. Also sent as the title of a LinkedIn video; other platforms ignore it.",
      +  "maxLength": 200,
      +  "type": "string"
      +}
  2. Changed4 schema fields changed
    • addedInput schema / properties / idempotency_key / example
      Added value: +"order-123:create-post:v1"
    • addedInput schema / properties / idempotency_key / maxLength
      Added value: +255
    • addedInput schema / properties / idempotency_key / minLength
      Added value: +1
    • addedInput schema / properties / idempotency_key / pattern
      Added value: +"^[\\x21-\\x7E]{1,255}$"
  3. Changed1 schema field changed
    • changedInput schema / properties / workspace_id / description
      Previous value: -"Workspace to operate in. Do not ask the user for this UUID — call aidelly_list_workspaces and use the `id` of the matching workspace. Optional for read operations; required when creating content."New value: +"Workspace to operate in: the `id` of a workspace returned by aidelly_list_workspaces. Optional for read operations; required when creating content."
  4. Changed4 schema fields changed
    • changedInput schema / properties / posts / items / properties / content / properties / media / description
      Previous value: -"Media attachments. Supplying multiple items automatically creates a carousel/slideshow on platforms that support it (Instagram, Facebook, TikTok).\nUse `read_url` returned by `POST /media/upload-url` for each `media[].url`.\nTruncated or corrupt images are rejected at upload and publish preflight with a clear validation error.\n- **Instagram**: 2–10 images → carousel; 1 video → reel (or `platform_specific.contentType: \"reel\"`)\n- **TikTok**: all images → photo carousel; 1 video → video post or draft\n- **Facebook**: 2+ images → carousel; 1 video → video post\n"New value: +"Media attachments. Supplying multiple items automatically creates a carousel/slideshow on platforms that support it (Instagram, Facebook, TikTok).\nUse `read_url` returned by `POST /media/upload-url` for each `media[].url`.\nTruncated or corrupt images are rejected at upload and publish preflight with a clear validation error.\nWhen `type` is omitted it is resolved from the media-library row (`application/pdf` → `document`), so an uploaded PDF is no longer stored as an image.\n- **Instagram**: 2–10 images → carousel; 1 video → reel (or `platform_specific.contentType: \"reel\"`)\n- **TikTok**: all images → photo carousel; 1 video → video post or draft\n- **Facebook**: 2+ images → carousel; 1 video → video post\n- **LinkedIn**: one `type: \"document\"` PDF (≤100 MB, ≤300 pages) → swipeable document post. Documents are LinkedIn-only and cannot be mixed with images or videos; other platforms return `422 PUBLIC_API_DOCUMENT_UNSUPPORTED_PLATFORM`. The size and format checks run at create time; the page-count check runs at publish.\n"
    • addedInput schema / properties / posts / items / properties / content / properties / media / items / properties / type / description
      Added value: +"Attachment kind. Optional — resolved from the media-library row when omitted. `document` is LinkedIn-only."
    • changedInput schema / properties / posts / items / properties / content / properties / media / items / properties / type / enum
      Previous value: -[
      -  "image",
      -  "video",
      -  "gif"
      -]New value: +[
      +  "image",
      +  "video",
      +  "gif",
      +  "document"
      +]
    • changedInput schema / properties / posts / items / properties / content / properties / thread / properties / parts / items / properties / media / items / properties / type / enum
      Previous value: -[
      -  "image",
      -  "video",
      -  "gif"
      -]New value: +[
      +  "image",
      +  "video",
      +  "gif",
      +  "document"
      +]
  5. Changed3 schema fields changed
    • addedInput schema / properties / posts / items / properties / content / properties / facebook_destination
      Added value: +{
      +  "description": "Facebook destination for posts. Use \"stories\" for a Page Story only or \"post_stories\" for feed + Story. Behind the FACEBOOK_STORIES_ENABLED feature flag.",
      +  "enum": [
      +    "post",
      +    "stories",
      +    "post_stories"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / posts / items / properties / content / properties / platform_specific / description
      Previous value: -"Platform-specific options. Supported fields per platform:\n\n**Instagram**\n- `contentType` (`string`): `\"post\"` | `\"reel\"` | `\"story\"`. Defaults to `\"reel\"` for a single video, `\"carousel\"` for multiple images, `\"post\"` otherwise.\n- `instagramDestination` / `instagram_destination` (`string`): `\"post\"` | `\"stories\"` | `\"post_stories\"`. Use `stories` for Story-only or `post_stories` for feed + Story.\n- `reelOptions.shareToFeed` (`boolean`): Share reel to feed. Default `true`.\n- `reelOptions.trialReel.enabled` (`boolean`): Publish as a trial reel to non-followers first. When enabled, `shareToFeed` is forced to `false`.\n- `reelOptions.trialReel.graduationStrategy` (`string`): Required for trial reels. `\"MANUAL\"` graduates in Instagram; `\"SS_PERFORMANCE\"` graduates automatically based on performance.\n\n**TikTok**\n- `postMode` (`string`): `\"direct\"` (publish immediately) | `\"draft\"` (save to inbox for review). Default `\"direct\"`.\n- `postAsDraft` (`boolean`): Shorthand for `postMode: \"draft\"`.\n- `title` (`string`): Optional title shown in the TikTok inbox when posting as draft.\n- Aliases accepted for agents and normalized to camelCase: `post_mode`, `post_as_draft`, `publish_immediately`.\n- `photos` (`array`): For photo carousels — array of `{ url, order, caption? }` objects (max 35). When all media items are images, TikTok automatically creates a photo carousel.\n- `allowComments` (`boolean`), `allowDuet` (`boolean`), `allowStitch` (`boolean`): Interaction controls.\n\n**Facebook**\n- `fbPostType` (`string`): `\"photo\"` | `\"carousel\"`. Post type. `\"carousel\"` enables multi-card experience with child attachments. Defaults to `\"photo\"`.\n- `fbCarouselLink` (`string`): Destination link for all cards in a carousel. Required when `fbPostType=\"carousel\"`.\n- `fbCarouselCards` (`array`): Optional per-card copy for carousel posts. Array of objects with `name` and `description` strings (max 5 items), index-aligned with media attachments. Example: `[{ name: \"Card 1\", description: \"First card\" }, { name: \"Card 2\", description: \"Second card\" }]`.\n- `enableFirstComment` (`boolean`): Post an auto-comment after publishing.\n- `firstCommentText` (`string`): Text for the auto-comment.\n\n**Facebook Carousel Behavior (backward compatible)**\nSet `fbPostType=\"carousel\"` to opt in to carousel format. When `fbPostType` is absent or set to `\"photo\"`, the default behavior is used (single photo or video post). Absent or `\"photo\"` = backward compatible behavior.\n\n**Pinterest**\n- `board_id` / `boardId` (`string`): Board id returned by `GET /accounts/pinterest/boards`. When omitted, Aidelly resolves a board in this order: (1) value in the request payload, (2) board saved on the connected Pinterest account (`platform_specific`), (3) workspace posting default, (4) user-level posting default. Publishing fails preflight if no board can be resolved.\n\n**LinkedIn**\n- `contentType` (`string`): `\"post\"` | `\"image\"` | `\"video\"` — auto-detected from media if not specified.\n\n**Threads**\n- `replyControl` (`string`): `\"everyone\"` | `\"accounts_you_follow\"` | `\"mentioned_only\"`. Maps to the Threads API `reply_control` field. Defaults to the connection's saved Threads posting default, then `\"everyone\"`.\n- `topicTag` (`string`): A single topic tag (Threads accepts at most one per post). Maps to `topic_tag`.\n- `allowlistedCountryCodes` (`string[]`): ISO-3166 alpha-2 country codes that are allowed to see the post. Maps to `allowlisted_country_codes`. Empty array publishes globally.\n- `linkAttachmentUrl` (`string`): URL to attach as the canonical link preview. Maps to `link_attachment`.\n\n**Google Business** (`google_business`)\n- `locationName` (`string`, required): Full GBP location resource name, e.g. `accounts/{accountId}/locations/{locationId}`. Use the `id` from `/accounts` for a `google_business` row. Falls back to the connection's saved default location when omitted.\n- `topicType` (`string`): `\"STANDARD\"` | `\"EVENT\"` | `\"OFFER\"` | `\"ALERT\"`. Defaults to `\"STANDARD\"`.\n- `languageCode` (`string`): BCP-47 language tag (e.g. `\"en-US\"`). Defaults to `\"en-US\"`.\n- `callToActionType` (`string`): `\"BOOK\"` | `\"ORDER\"` | `\"SHOP\"` | `\"LEARN_MORE\"` | `\"SIGN_UP\"` | `\"CALL\"`. Adds a CTA button to STANDARD posts only.\n- `callToActionUrl` (`string`): Required for every CTA except `CALL`, which uses the phone number on the Business Profile.\n- `event` (`object`, required when `topicType` is `\"EVENT\"`): `{ title, schedule }` where `schedule` accepts ISO `start`/`end` strings or Google date/time objects (`startDate`, `startTime`, `endDate`, `endTime`).\n- `offer` (`object`, required when `topicType` is `\"OFFER\"`): `{ schedule, couponCode?, redeemOnlineUrl?, termsConditions? }`.\n- `alertType` (`string`, required when `topicType` is `\"ALERT\"`): Currently `\"COVID_19\"`.\n"New value: +"Platform-specific options. Supported fields per platform:\n\n**Instagram**\n- `contentType` (`string`): `\"post\"` | `\"reel\"` | `\"story\"`. Defaults to `\"reel\"` for a single video, `\"carousel\"` for multiple images, `\"post\"` otherwise.\n- `instagramDestination` / `instagram_destination` (`string`): `\"post\"` | `\"stories\"` | `\"post_stories\"`. Use `stories` for Story-only or `post_stories` for feed + Story.\n- `reelOptions.shareToFeed` (`boolean`): Share reel to feed. Default `true`.\n- `reelOptions.trialReel.enabled` (`boolean`): Publish as a trial reel to non-followers first. When enabled, `shareToFeed` is forced to `false`.\n- `reelOptions.trialReel.graduationStrategy` (`string`): Required for trial reels. `\"MANUAL\"` graduates in Instagram; `\"SS_PERFORMANCE\"` graduates automatically based on performance.\n\n**TikTok**\n- `postMode` (`string`): `\"direct\"` (publish immediately) | `\"draft\"` (save to inbox for review). Default `\"direct\"`.\n- `postAsDraft` (`boolean`): Shorthand for `postMode: \"draft\"`.\n- `title` (`string`): Optional title shown in the TikTok inbox when posting as draft.\n- Aliases accepted for agents and normalized to camelCase: `post_mode`, `post_as_draft`, `publish_immediately`.\n- `photos` (`array`): For photo carousels — array of `{ url, order, caption? }` objects (max 35). When all media items are images, TikTok automatically creates a photo carousel.\n- `allowComments` (`boolean`), `allowDuet` (`boolean`), `allowStitch` (`boolean`): Interaction controls.\n\n**Facebook**\n- `fbPostType` (`string`): `\"photo\"` | `\"carousel\"`. Post type. `\"carousel\"` enables multi-card experience with child attachments. Defaults to `\"photo\"`.\n- `fbCarouselLink` (`string`): Destination link for all cards in a carousel. Required when `fbPostType=\"carousel\"`.\n- `fbCarouselCards` (`array`): Optional per-card copy for carousel posts. Array of objects with `name` and `description` strings (max 5 items), index-aligned with media attachments. Example: `[{ name: \"Card 1\", description: \"First card\" }, { name: \"Card 2\", description: \"Second card\" }]`.\n- `enableFirstComment` (`boolean`): Post an auto-comment after publishing.\n- `firstCommentText` (`string`): Text for the auto-comment.\n- `facebookDestination` / `facebook_destination` (`string`): `\"post\"` | `\"stories\"` | `\"post_stories\"`. Publishes a Page Story via `/photo_stories` or `/video_stories`. Story media must be 9:16; videos 3-60s (MP4/MOV); photos JPEG/PNG/BMP/GIF/TIFF under 10MB. Behind the `FACEBOOK_STORIES_ENABLED` feature flag.\n\n**Facebook Carousel Behavior (backward compatible)**\nSet `fbPostType=\"carousel\"` to opt in to carousel format. When `fbPostType` is absent or set to `\"photo\"`, the default behavior is used (single photo or video post). Absent or `\"photo\"` = backward compatible behavior.\n\n**Pinterest**\n- `board_id` / `boardId` (`string`): Board id returned by `GET /accounts/pinterest/boards`. When omitted, Aidelly resolves a board in this order: (1) value in the request payload, (2) board saved on the connected Pinterest account (`platform_specific`), (3) workspace posting default, (4) user-level posting default. Publishing fails preflight if no board can be resolved.\n\n**LinkedIn**\n- `contentType` (`string`): `\"post\"` | `\"image\"` | `\"video\"` — auto-detected from media if not specified.\n\n**Threads**\n- `replyControl` (`string`): `\"everyone\"` | `\"accounts_you_follow\"` | `\"mentioned_only\"`. Maps to the Threads API `reply_control` field. Defaults to the connection's saved Threads posting default, then `\"everyone\"`.\n- `topicTag` (`string`): A single topic tag (Threads accepts at most one per post). Maps to `topic_tag`.\n- `allowlistedCountryCodes` (`string[]`): ISO-3166 alpha-2 country codes that are allowed to see the post. Maps to `allowlisted_country_codes`. Empty array publishes globally.\n- `linkAttachmentUrl` (`string`): URL to attach as the canonical link preview. Maps to `link_attachment`.\n\n**Google Business** (`google_business`)\n- `locationName` (`string`, required): Full GBP location resource name, e.g. `accounts/{accountId}/locations/{locationId}`. Use the `id` from `/accounts` for a `google_business` row. Falls back to the connection's saved default location when omitted.\n- `topicType` (`string`): `\"STANDARD\"` | `\"EVENT\"` | `\"OFFER\"` | `\"ALERT\"`. Defaults to `\"STANDARD\"`.\n- `languageCode` (`string`): BCP-47 language tag (e.g. `\"en-US\"`). Defaults to `\"en-US\"`.\n- `callToActionType` (`string`): `\"BOOK\"` | `\"ORDER\"` | `\"SHOP\"` | `\"LEARN_MORE\"` | `\"SIGN_UP\"` | `\"CALL\"`. Adds a CTA button to STANDARD posts only.\n- `callToActionUrl` (`string`): Required for every CTA except `CALL`, which uses the phone number on the Business Profile.\n- `event` (`object`, required when `topicType` is `\"EVENT\"`): `{ title, schedule }` where `schedule` accepts ISO `start`/`end` strings or Google date/time objects (`startDate`, `startTime`, `endDate`, `endTime`).\n- `offer` (`object`, required when `topicType` is `\"OFFER\"`): `{ schedule, couponCode?, redeemOnlineUrl?, termsConditions? }`.\n- `alertType` (`string`, required when `topicType` is `\"ALERT\"`): Currently `\"COVID_19\"`.\n"
    • addedInput schema / properties / posts / items / properties / facebook_destination
      Added value: +{
      +  "description": "Facebook-only destination. Use post for feed only, stories for a Page Story only, or post_stories for both. Behind the FACEBOOK_STORIES_ENABLED feature flag - requests that set it while the flag is off are rejected with a validation error.",
      +  "enum": [
      +    "post",
      +    "stories",
      +    "post_stories"
      +  ],
      +  "type": "string"
      +}
  6. Changed2 schema fields changed
    • changedInput schema / properties / posts / description
      Previous value: -"Posts to create. Each item matches aidelly_create_post. Max 50 per call."New value: +"Posts to create. Max 50 per request."
    • changedInput schema / required
      Previous value: -[
      -  "posts",
      -  "idempotency_key"
      -]New value: +[
      +  "idempotency_key",
      +  "posts"
      +]
  7. Added

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses behavior the annotations do not: 201 vs 207 status semantics, the per-item results array with index/status, the distinction between acceptance and delivery, per-post rate-limit accounting, and all-or-nothing preflight rejection when the daily scheduling limit would be exceeded. The idempotentHint=false annotation is not contradicted — the description correctly scopes idempotency to repeat calls carrying the same key.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then shape reference, then return contract, then cost model, then platform caveat, then retry semantics. Every sentence delivers a distinct operational fact; nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, 6 parameters, and deep nested item objects, the description covers the response contract and failure modes well. Minor gaps: it doesn't clarify that scheduled_at is per-item optional despite the tool being framed as scheduling, and it doesn't mention what happens to a partially failed 207 batch on retry beyond the idempotency note.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, and the description fills the most important gap by explaining idempotency_key's retry contract, which the schema only defines as a pattern. It also restates the 50-item cap and the LinkedIn document constraints (redundant with the schema media description). It says nothing about brand_id, workspace_id, or the body/query override parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb, resource, and scope: 'Create up to 50 scheduled posts in one call.' It also distinguishes itself from the single-post sibling by noting each item 'takes the same shape as aidelly_create_post', so an agent knows the relationship without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete selection signal — batches save round trips but not quota, since rate limit is charged per post — which tells the agent when batching is and isn't worth it. It also covers the retry case via idempotency_key. It stops short of explicitly saying 'use aidelly_create_post for a single post,' so the alternative is implied rather than named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.