{
  "openapi": "3.1.0",
  "info": {
    "title": "TryPost API",
    "version": "2.0.0",
    "description": "REST API for TryPost. Authenticate with a workspace API key as a Bearer token."
  },
  "servers": [
    {
      "url": "https://app.trypost.it/api",
      "description": "TryPost Cloud"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Posts",
      "description": "Create, read, update, delete and preview posts."
    },
    {
      "name": "Post notes",
      "description": "Internal notes on a post, visible to workspace members."
    },
    {
      "name": "Approvals",
      "description": "Approve or reject posts waiting for approval."
    },
    {
      "name": "Recurrence",
      "description": "Make a post repeat on a schedule."
    },
    {
      "name": "Media and uploads",
      "description": "Upload files and attach media to posts."
    },
    {
      "name": "Social accounts",
      "description": "Connected social accounts and their network-specific options."
    },
    {
      "name": "Channels",
      "description": "A channel's posting schedule and queue."
    },
    {
      "name": "Ideas",
      "description": "Ideas on the Create board."
    },
    {
      "name": "Idea stages",
      "description": "The groups (columns) of the ideas board."
    },
    {
      "name": "Analytics",
      "description": "Workspace and channel insights."
    },
    {
      "name": "Labels",
      "description": "Labels to organize posts and ideas."
    },
    {
      "name": "Signatures",
      "description": "Reusable text to append to posts."
    },
    {
      "name": "Workspace",
      "description": "The workspace the API key belongs to."
    },
    {
      "name": "API keys",
      "description": "Personal API keys for this workspace."
    },
    {
      "name": "Webhooks",
      "description": "Outgoing webhooks and their delivery logs."
    },
    {
      "name": "Repurposes",
      "description": "Automations that republish videos posted outside TryPost."
    },
    {
      "name": "Platform",
      "description": "Platform capabilities and content types."
    }
  ],
  "paths": {
    "/posts": {
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "List posts",
        "operationId": "listPosts",
        "description": "Lists the workspace's posts: posts without a time first, then by scheduled time, latest first, with their destinations and labels. Pending approval requests of other members are included (API keys belong to admins, who can approve). Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "channels[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only posts on these social accounts. Values that are not UUIDs are ignored. When no value is a UUID, the filter is not applied.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          {
            "name": "labels[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only posts with any of these labels. Values that are not UUIDs are ignored. When no value is a UUID, the filter is not applied.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          {
            "name": "untagged",
            "in": "query",
            "required": false,
            "description": "Only posts without labels (combined with `labels[]`, posts matching either).",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of posts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Post"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                      "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                      "author": {
                        "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                        "name": "Ana Souza"
                      },
                      "content": "We just shipped scheduled threads. Here is how they work.",
                      "media": [
                        {
                          "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                          "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                          "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                          "type": "image",
                          "mime_type": "image/jpeg",
                          "original_filename": "launch.jpg",
                          "size": 482113,
                          "meta": {
                            "width": 1080,
                            "height": 1350,
                            "alt_text": "Product launch banner"
                          }
                        }
                      ],
                      "status": "scheduled",
                      "schedule_mode": "custom",
                      "scheduled_at": "2026-10-12 14:00:00",
                      "published_at": null,
                      "approval_requested_by": null,
                      "approval_requested_at": null,
                      "approved_by": null,
                      "approved_at": null,
                      "recurrence": null,
                      "origin": "trypost",
                      "platforms": [
                        {
                          "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                          "platform": "x",
                          "content_type": "x_post",
                          "meta": [],
                          "status": "pending",
                          "enabled": true,
                          "platform_url": null,
                          "published_at": null,
                          "error_message": null,
                          "display_name": "TryPost",
                          "display_username": "trypostit",
                          "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                          "social_account": {
                            "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                            "platform": "x",
                            "display_name": "TryPost",
                            "username": "trypostit",
                            "status": "connected",
                            "has_posting_schedule": true,
                            "timezone": "America/Sao_Paulo",
                            "posting_goal": 5,
                            "max_content_length": 280,
                            "long_posts": false,
                            "verified_badge": null
                          }
                        }
                      ],
                      "labels": [
                        {
                          "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                          "name": "Launch",
                          "color": "#2563EB",
                          "created_at": "2026-09-01 10:00:00",
                          "updated_at": "2026-09-01 10:00:00"
                        }
                      ],
                      "created_at": "2026-10-08 13:20:11",
                      "updated_at": "2026-10-08 13:20:11"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/posts?page=1",
                    "last": "https://app.trypost.it/api/posts?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/posts?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/posts",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Posts"
        ],
        "summary": "Create post",
        "operationId": "createPost",
        "description": "Creates one post on one social account.\n\n- `status: draft` (default) saves a draft.\n- `status: scheduled` with `scheduled_at` schedules it at that time; with `queue` (`next` or `top`) it takes a slot of the channel's posting schedule; with `queue_slot` it takes that exact free slot (from `GET /channels/{account}/queue/slots`).\n- `status: publishing` publishes it now.\n\nOmitted `content_type` is chosen like the app does: on Pinterest a video makes `pinterest_video_pin` and several images `pinterest_carousel`, on TikTok images only make `tiktok_photo`, every other network takes its default format.\n\nTo schedule or publish, the destination needs its required settings in `platforms[].meta` (see `PlatformMeta`). API keys belong to workspace admins, who publish directly, so a post created through the API is never stored as `pending_approval`.\n\nTo post the same text on several channels at once, use `POST /posts/batch`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "platforms"
                ],
                "properties": {
                  "content": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 25000,
                    "description": "Post text, at most 25000 characters. When `status` is `scheduled` or `publishing` it must also fit each account's limit (`max_content_length` of the social account, for example 280 on X or 25000 for X accounts with long posts, 300 on Bluesky, 500 on Mastodon including the content warning), measured on the text the network receives. A scheduled or published post needs text or media."
                  },
                  "media": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MediaReference"
                    },
                    "description": "Media in order. Each item is one of `upload_token`, `url` or `id`. Types the channel does not accept are refused."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "publishing"
                    ],
                    "description": "`draft` keeps the post editable. `scheduled` schedules it at `scheduled_at` or in the channel queue (`queue`). `publishing` publishes it now.",
                    "default": "draft"
                  },
                  "platforms": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Exactly one destination.",
                    "items": {
                      "type": "object",
                      "required": [
                        "social_account_id"
                      ],
                      "properties": {
                        "social_account_id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Social account of this workspace."
                        },
                        "content_type": {
                          "oneOf": [
                            {
                              "$ref": "#/components/schemas/ContentType"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Format; must belong to the account's network. Omitted, it is chosen from the media."
                        },
                        "meta": {
                          "$ref": "#/components/schemas/PlatformMeta"
                        }
                      }
                    }
                  },
                  "scheduled_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "When to publish, for `status: scheduled`. Any date string; must be in the future and before `2038-01-19`. Cannot be combined with `queue`. Required with `status: scheduled` unless `queue` or `queue_slot` is sent."
                  },
                  "queue": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "next",
                      "top",
                      null
                    ],
                    "description": "Queue position, only with `status: scheduled`. `next` takes the channel's first free slot; `top` takes its first slot and moves the queued posts behind it to the next gap. The channel must have posting times (`has_posting_schedule`). Cannot be combined with `scheduled_at`."
                  },
                  "queue_slot": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Instant of one free slot from `GET /channels/{account}/queue/slots`, only with `status: scheduled`. Stores the post as a queue post in that slot; refused when the slot is taken or held by a pending approval request. Before `2038-01-19`. Cannot be combined with `queue`. Takes the place of `scheduled_at` when both are sent."
                  },
                  "label_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Labels of this workspace."
                  }
                }
              },
              "example": {
                "content": "We just shipped scheduled threads. Here is how they work.",
                "status": "scheduled",
                "scheduled_at": "2026-10-12T14:00:00Z",
                "media": [
                  {
                    "url": "https://example.com/launch.jpg",
                    "alt": "Product launch banner"
                  }
                ],
                "platforms": [
                  {
                    "social_account_id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                    "content_type": "x_post",
                    "meta": {
                      "thread_replies": [
                        {
                          "text": "2/ Replies publish under the first post."
                        }
                      ]
                    }
                  }
                ],
                "label_ids": [
                  "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "custom",
                  "scheduled_at": "2026-10-12 14:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 13:20:11"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/batch": {
      "post": {
        "tags": [
          "Posts"
        ],
        "summary": "Create posts in batch",
        "operationId": "createPostsInBatch",
        "description": "Creates one independent post per destination, as the app does when several channels are selected. The posts share a `post_group_id`. Each destination may override the shared `content`, `media`, `content_type` and `meta`.\n\n`status: scheduled` schedules every post at `scheduled_at` or in each channel's queue (`queue: next` or `top`). One specific slot (`queue_slot`) is not taken here: use `POST /posts` or `PUT /channels/{account}/queue/slot`.\n\n`destinations[].meta` follows the same per-network rules as `platforms[].meta` (see `PlatformMeta`), checked with the destination's network; errors are reported on `destinations.N.meta.*`. To schedule or publish, every destination needs its required settings and text or media. API keys belong to workspace admins, so these posts are never stored as `pending_approval`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status",
                  "destinations"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "publishing"
                    ],
                    "description": "`draft` keeps the post editable. `scheduled` schedules it at `scheduled_at` or in the channel queue (`queue`). `publishing` publishes it now."
                  },
                  "content": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 25000,
                    "description": "Shared text, at most 25000 characters. When `status` is `scheduled` or `publishing` it must also fit each account's limit (`max_content_length` of the social account, for example 280 on X or 25000 for X accounts with long posts, 300 on Bluesky, 500 on Mastodon including the content warning), measured on the text the network receives. A scheduled or published post needs text or media."
                  },
                  "media": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MediaReference"
                    },
                    "description": "Shared media. Media in order. Each item is one of `upload_token`, `url` or `id`. Types the channel does not accept are refused."
                  },
                  "scheduled_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "When to publish, for `status: scheduled`. Any date string; must be in the future and before `2038-01-19`. Cannot be combined with `queue`. Required with `status: scheduled` unless `queue` is sent."
                  },
                  "queue": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "next",
                      "top",
                      null
                    ],
                    "description": "Queue position, only with `status: scheduled`. `next` takes the channel's first free slot; `top` takes its first slot and moves the queued posts behind it to the next gap. Every channel must have posting times (`has_posting_schedule`). Cannot be combined with `scheduled_at`."
                  },
                  "label_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Labels of this workspace."
                  },
                  "destinations": {
                    "type": "array",
                    "minItems": 1,
                    "description": "One entry per social account; each account at most once.",
                    "items": {
                      "type": "object",
                      "required": [
                        "social_account_id"
                      ],
                      "properties": {
                        "social_account_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "content_type": {
                          "oneOf": [
                            {
                              "$ref": "#/components/schemas/ContentType"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Must belong to the account's network. Omitted, it is chosen from the media."
                        },
                        "content": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "maxLength": 25000,
                          "description": "Replaces the shared text for this destination."
                        },
                        "media": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/MediaReference"
                          },
                          "description": "Replaces the shared media for this destination. An item without alt text takes the alt text of the same shared item."
                        },
                        "meta": {
                          "$ref": "#/components/schemas/PlatformMeta"
                        }
                      }
                    }
                  }
                }
              },
              "example": {
                "status": "scheduled",
                "queue": "next",
                "content": "Our October changelog is live.",
                "media": [
                  {
                    "upload_token": "4f6c2b1e-8d3a-4e5f-9a7b-1c2d3e4f5a6b",
                    "alt": "Changelog cover"
                  }
                ],
                "destinations": [
                  {
                    "social_account_id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                    "content_type": "x_post"
                  },
                  {
                    "social_account_id": "9c8b7a65-5e4f-4a3b-9c2d-1e0f9a8b7c65",
                    "content_type": "pinterest_pin",
                    "content": "Everything we shipped in October, in one pin.",
                    "meta": {
                      "board_id": "1022106146620830917",
                      "title": "October changelog",
                      "link": "https://trypost.it/changelog"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created posts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "posts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Post"
                      }
                    }
                  }
                },
                "example": {
                  "posts": [
                    {
                      "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                      "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                      "author": {
                        "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                        "name": "Ana Souza"
                      },
                      "content": "Our October changelog is live.",
                      "media": [
                        {
                          "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                          "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                          "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                          "type": "image",
                          "mime_type": "image/jpeg",
                          "original_filename": "launch.jpg",
                          "size": 482113,
                          "meta": {
                            "width": 1080,
                            "height": 1350,
                            "alt_text": "Changelog cover"
                          }
                        }
                      ],
                      "status": "scheduled",
                      "schedule_mode": "queue",
                      "scheduled_at": "2026-10-12 14:00:00",
                      "published_at": null,
                      "approval_requested_by": null,
                      "approval_requested_at": null,
                      "approved_by": null,
                      "approved_at": null,
                      "recurrence": null,
                      "origin": "trypost",
                      "platforms": [
                        {
                          "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                          "platform": "x",
                          "content_type": "x_post",
                          "meta": {
                            "thread_replies": [
                              {
                                "text": "2/ Replies publish under the first post.",
                                "media": []
                              }
                            ]
                          },
                          "status": "pending",
                          "enabled": true,
                          "platform_url": null,
                          "published_at": null,
                          "error_message": null,
                          "display_name": "TryPost",
                          "display_username": "trypostit",
                          "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                          "social_account": {
                            "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                            "platform": "x",
                            "display_name": "TryPost",
                            "username": "trypostit",
                            "status": "connected",
                            "has_posting_schedule": true,
                            "timezone": "America/Sao_Paulo",
                            "posting_goal": 5,
                            "max_content_length": 280,
                            "long_posts": false,
                            "verified_badge": null
                          }
                        }
                      ],
                      "labels": [
                        {
                          "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                          "name": "Launch",
                          "color": "#2563EB",
                          "created_at": "2026-09-01 10:00:00",
                          "updated_at": "2026-09-01 10:00:00"
                        }
                      ],
                      "created_at": "2026-10-08 13:20:11",
                      "updated_at": "2026-10-08 13:20:11"
                    },
                    {
                      "id": "9d3c1f2a-7c5f-4d9b-8e2f-3b8c6d9e1f52",
                      "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                      "author": {
                        "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                        "name": "Ana Souza"
                      },
                      "content": "Everything we shipped in October, in one pin.",
                      "media": [
                        {
                          "id": "9d3c1f31-9b0c-4d1e-8f2a-3b4c5d6e7f80",
                          "path": "medias/9d3c1f31-9b0c-4d1e-8f2a-3b4c5d6e7f80.jpg",
                          "url": "https://media.trypost.it/medias/9d3c1f31-9b0c-4d1e-8f2a-3b4c5d6e7f80.jpg",
                          "type": "image",
                          "mime_type": "image/jpeg",
                          "original_filename": "launch.jpg",
                          "size": 482113,
                          "meta": {
                            "width": 1080,
                            "height": 1350,
                            "alt_text": "Changelog cover"
                          }
                        }
                      ],
                      "status": "scheduled",
                      "schedule_mode": "queue",
                      "scheduled_at": "2026-10-12 14:00:00",
                      "published_at": null,
                      "approval_requested_by": null,
                      "approval_requested_at": null,
                      "approved_by": null,
                      "approved_at": null,
                      "recurrence": null,
                      "origin": "trypost",
                      "platforms": [
                        {
                          "id": "9d3c1f2b-2b3c-4d4e-9f5a-6b7c8d9e0f21",
                          "platform": "pinterest",
                          "content_type": "pinterest_pin",
                          "meta": {
                            "board_id": "1022106146620830917",
                            "title": "October changelog",
                            "link": "https://trypost.it/changelog"
                          },
                          "status": "pending",
                          "enabled": true,
                          "platform_url": null,
                          "published_at": null,
                          "error_message": null,
                          "display_name": "TryPost",
                          "display_username": "trypostit",
                          "display_avatar": null,
                          "social_account": {
                            "id": "9c8b7a65-5e4f-4a3b-9c2d-1e0f9a8b7c65",
                            "platform": "pinterest",
                            "display_name": "TryPost",
                            "username": "trypostit",
                            "status": "connected",
                            "has_posting_schedule": true,
                            "timezone": "UTC",
                            "posting_goal": 5,
                            "max_content_length": 800,
                            "long_posts": false,
                            "verified_badge": null
                          }
                        }
                      ],
                      "labels": [
                        {
                          "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                          "name": "Launch",
                          "color": "#2563EB",
                          "created_at": "2026-09-01 10:00:00",
                          "updated_at": "2026-09-01 10:00:00"
                        }
                      ],
                      "created_at": "2026-10-08 13:20:11",
                      "updated_at": "2026-10-08 13:20:11"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "Get post",
        "operationId": "getPost",
        "description": "Returns one post with its destinations and labels.",
        "responses": {
          "200": {
            "description": "The post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "custom",
                  "scheduled_at": "2026-10-12 14:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 13:20:11"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "put": {
        "tags": [
          "Posts"
        ],
        "summary": "Update post",
        "operationId": "updatePost",
        "description": "Updates a post. Only the fields you send change. The social account is fixed (`social_account_id` is refused).\n\nSend the destination's format and settings either as top-level `content_type` and `meta` (the post has one destination), or as `platforms[]` with the destination `id`. `meta` is merged with the stored settings: send `null` for a key to clear it (string, list and object settings; boolean settings cannot be cleared, so send `true` or `false`); `thread_replies` replaces the whole list. `media` replaces the post's media; `label_ids` replaces its labels.\n\n`status: publishing` publishes the post now; `scheduled` schedules it at `scheduled_at`, in the queue (`queue`), or keeps its future `scheduled_at`; `draft` unschedules it (it is no longer published; the last `scheduled_at` stays on the draft). When scheduling or publishing, the content type must fit the media and the required settings must be present.\n\nPosts that are publishing, published, partially published or failed cannot be edited: the request returns `422` with `This post has already been processed and cannot be re-published. Duplicate it to try again.`\n\nPosts with several destinations (created before each channel got its own post) cannot be queued; `platforms` there lists the destinations to keep, and the rest are turned off. On this endpoint an invalid body may answer `422` before the `404` check of a post of another workspace.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 25000,
                    "description": "Post text, at most 25000 characters. When `status` is `scheduled` or `publishing` it must also fit each account's limit (`max_content_length` of the social account, for example 280 on X or 25000 for X accounts with long posts, 300 on Bluesky, 500 on Mastodon including the content warning), measured on the text the network receives. A scheduled or published post needs text or media."
                  },
                  "media": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/MediaReference"
                    },
                    "description": "Replaces the post's media. Omit it to keep the current media. Media in order. Each item is one of `upload_token`, `url` or `id`. Types the channel does not accept are refused."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "scheduled",
                      "publishing"
                    ],
                    "description": "`draft` keeps the post editable. `scheduled` schedules it at `scheduled_at` or in the channel queue (`queue`). `publishing` publishes it now. Omit it to keep the current status."
                  },
                  "content_type": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/ContentType"
                      }
                    ],
                    "description": "New format for the post's destination. Omitted, the stored format is kept, except on Pinterest and TikTok where new media decides it as on create."
                  },
                  "meta": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/PlatformMeta"
                      }
                    ],
                    "description": "Settings of the post's destination, merged with the stored ones."
                  },
                  "platforms": {
                    "type": "array",
                    "description": "Alternative to top-level `content_type` / `meta`. On a post with several destinations, the destinations not listed are turned off.",
                    "items": {
                      "type": "object",
                      "required": [
                        "id"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "An enabled destination of this post (`platforms[].id` in the post)."
                        },
                        "content_type": {
                          "$ref": "#/components/schemas/ContentType"
                        },
                        "meta": {
                          "$ref": "#/components/schemas/PlatformMeta"
                        }
                      }
                    }
                  },
                  "scheduled_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "With `status: scheduled`: required unless `queue` is sent or the post already has a future time; must be in the future and before `2038-01-19`. Cannot be combined with `queue`."
                  },
                  "queue": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "enum": [
                      "next",
                      "top",
                      null
                    ],
                    "description": "Queue position, only with `status: scheduled`. `next` takes the channel's first free slot; `top` takes its first slot and moves the queued posts behind it to the next gap. The channel must have posting times (`has_posting_schedule`). Cannot be combined with `scheduled_at`. Refused on posts with several destinations."
                  },
                  "label_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Replaces the post's labels."
                  }
                }
              },
              "example": {
                "content": "We just shipped scheduled threads (and a few fixes).",
                "status": "scheduled",
                "queue": "next",
                "meta": {
                  "thread_replies": [
                    {
                      "text": "2/ Replies publish under the first post."
                    },
                    {
                      "text": "3/ Full changelog below.",
                      "media": [
                        {
                          "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads (and a few fixes).",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "queue",
                  "scheduled_at": "2026-10-13 12:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          },
                          {
                            "text": "3/ Full changelog below.",
                            "media": [
                              {
                                "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                                "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                                "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                                "type": "image",
                                "mime_type": "image/jpeg",
                                "original_filename": "launch.jpg",
                                "size": 482113,
                                "meta": {
                                  "width": 1080,
                                  "height": 1350,
                                  "alt_text": "Product launch banner"
                                }
                              }
                            ]
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 15:41:07"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Posts"
        ],
        "summary": "Delete post",
        "operationId": "deletePost",
        "description": "Deletes a post that has not been sent, with its media. Nothing is removed from the network. Posts that are publishing, published, partially published or failed cannot be deleted: the request returns `422` with `Sent posts cannot be deleted.` on `post`.",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/metrics": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "Get post metrics",
        "operationId": "getPostMetrics",
        "description": "Returns the saved analytics of each enabled destination: the latest daily snapshot TryPost collected from the network. No call is made to the network. LinkedIn, LinkedIn Page, Telegram, Discord and Google Business are not in analytics.",
        "responses": {
          "200": {
            "description": "Metrics per destination.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostMetrics"
                },
                "example": {
                  "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "platforms": [
                    {
                      "post_platform_id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "status": "published",
                      "platform_post_id": "1843921066571337728",
                      "platform_url": "https://x.com/trypostit/status/1843921066571337728",
                      "metrics": {
                        "available": true,
                        "reason": null,
                        "publication": {
                          "id": "9d4a0b1c-2d3e-4f5a-8b6c-7d8e9f0a1b2c",
                          "post_platform_id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                          "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                          "platform": "x",
                          "origin": "trypost",
                          "content_type": "text",
                          "availability": "available",
                          "provider_published_at": "2026-10-12T14:00:03+00:00",
                          "permalink": "https://x.com/trypostit/status/1843921066571337728",
                          "excerpt": "We just shipped scheduled threads.",
                          "preview_metadata": null,
                          "account_display_name": "TryPost",
                          "account_username": "trypostit",
                          "account_avatar_url": null
                        },
                        "snapshot": {
                          "date": "2026-10-14",
                          "collected_at": "2026-10-14T06:10:00+00:00",
                          "provider_observed_at": "2026-10-14T06:09:58+00:00",
                          "reactions_count": 42,
                          "comments_count": 5,
                          "shares_count": 7,
                          "saves_count": 3,
                          "views_count": null,
                          "impressions_count": 3120,
                          "reach_count": null,
                          "engagement_count": 57,
                          "exposure_count": 3120,
                          "exposure_kind": "impressions",
                          "watch_time_milliseconds": null,
                          "average_watch_time_milliseconds": null
                        },
                        "metrics": {
                          "impressions": {
                            "value": 3120,
                            "unit": "count",
                            "time_basis": "lifetime",
                            "precision": "exact",
                            "availability": "available",
                            "provider_metric": "impression_count",
                            "period_start": null,
                            "period_end": null
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/preview": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "get": {
        "tags": [
          "Posts"
        ],
        "summary": "Get post preview",
        "operationId": "getPostPreview",
        "description": "Shows the text each enabled destination will send, after the network's formatting rules, and its length against the account's limit. Nothing is published.",
        "responses": {
          "200": {
            "description": "Preview per destination.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostPreview"
                },
                "example": {
                  "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "original_content": "We just shipped scheduled threads. Here is how they work.",
                  "original_length": 57,
                  "platforms": [
                    {
                      "post_platform_id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "sanitized_content": "We just shipped scheduled threads. Here is how they work.",
                      "sanitized_length": 57,
                      "max_content_length": 280,
                      "truncated": false,
                      "thread_replies": [
                        {
                          "text": "2/ Replies publish under the first post.",
                          "media": []
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/notes": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "get": {
        "tags": [
          "Post notes"
        ],
        "summary": "List post notes",
        "operationId": "listPostNotes",
        "description": "Lists the post's notes, newest first. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of notes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PostNote"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9d3c2a10-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
                      "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                      "body": "Can we swap the image for the dark version?",
                      "author": {
                        "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                        "name": "Ana Souza",
                        "photo_url": "https://media.trypost.it/medias/9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e.jpg"
                      },
                      "created_at": "2026-10-08 14:02:45",
                      "updated_at": "2026-10-08 14:02:45"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/posts/9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41/notes?page=1",
                    "last": "https://app.trypost.it/api/posts/9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41/notes?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/posts/9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41/notes?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/posts/9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41/notes",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Post notes"
        ],
        "summary": "Create post note",
        "operationId": "createPostNote",
        "description": "Adds an internal note to a post as the API key's user. Notes are never published. Every other workspace member is emailed about it (unless they turned that email off in their notification preferences); on a post pending approval, only the approvers and the member who asked are.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "body"
                ],
                "properties": {
                  "body": {
                    "type": "string",
                    "maxLength": 2000
                  }
                }
              },
              "example": {
                "body": "Can we swap the image for the dark version?"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created note.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostNote"
                },
                "example": {
                  "id": "9d3c2a10-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
                  "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "body": "Can we swap the image for the dark version?",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza",
                    "photo_url": "https://media.trypost.it/medias/9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e.jpg"
                  },
                  "created_at": "2026-10-08 14:02:45",
                  "updated_at": "2026-10-08 14:02:45"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/notes/{note}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        },
        {
          "$ref": "#/components/parameters/NoteId"
        }
      ],
      "put": {
        "tags": [
          "Post notes"
        ],
        "summary": "Update post note",
        "operationId": "updatePostNote",
        "description": "Changes a note's text. Only the note's author can edit it (`403` with `This action is unauthorized.` otherwise). A note of another post returns `404`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "body"
                ],
                "properties": {
                  "body": {
                    "type": "string",
                    "maxLength": 2000
                  }
                }
              },
              "example": {
                "body": "Can we swap the image for the dark version?"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated note.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostNote"
                },
                "example": {
                  "id": "9d3c2a10-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
                  "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "body": "Can we swap the image for the dark version?",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza",
                    "photo_url": "https://media.trypost.it/medias/9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e.jpg"
                  },
                  "created_at": "2026-10-08 14:02:45",
                  "updated_at": "2026-10-08 14:02:45"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Post notes"
        ],
        "summary": "Delete post note",
        "operationId": "deletePostNote",
        "description": "Deletes a note. Only the note's author can delete it (`403` with `This action is unauthorized.` otherwise). A note of another post returns `404`.",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/approve": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "post": {
        "tags": [
          "Approvals"
        ],
        "summary": "Approve post",
        "operationId": "approvePost",
        "description": "Approves a post waiting for approval (`pending_approval`). With an empty body the post is scheduled as requested: in the queue position or at the time the member asked for. Send `scheduled_at` to pick another time, or `publish_now` to publish it now. When the requested time has passed (or the member asked to publish now) and neither is sent, the request fails with `422` on `scheduled_at`: `The requested time has passed. Choose a new time.` A post that is no longer pending fails with `422`: `This post is no longer waiting for approval.` The member who asked is emailed about the decision.\n\nAPI keys belong to workspace admins, who publish directly, so posts created or edited through the API never wait for approval. These endpoints decide the requests of members who need approval.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "publish_now": {
                    "type": "boolean",
                    "description": "Publish now instead of at the requested time. Cannot be combined with `scheduled_at`."
                  },
                  "scheduled_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "New time; in the future and before `2038-01-19`. Cannot be combined with `publish_now`."
                  }
                }
              },
              "example": {
                "scheduled_at": "2026-10-13T15:00:00Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The approved post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "custom",
                  "scheduled_at": "2026-10-13 15:00:00",
                  "published_at": null,
                  "approval_requested_by": {
                    "id": "9b4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b",
                    "name": "Bruno Lima"
                  },
                  "approval_requested_at": "2026-10-08 12:00:00",
                  "approved_by": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "approved_at": "2026-10-08 13:30:00",
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 13:30:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/reject": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "post": {
        "tags": [
          "Approvals"
        ],
        "summary": "Reject post",
        "operationId": "rejectPost",
        "description": "Rejects a post waiting for approval. The post goes back to `draft`; no reason is stored. The member who asked is emailed about the decision. A post that is no longer pending fails with `422`.\n\nAPI keys belong to workspace admins, who publish directly, so posts created or edited through the API never wait for approval. These endpoints decide the requests of members who need approval.",
        "responses": {
          "200": {
            "description": "The rejected post, now a draft.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "draft",
                  "schedule_mode": null,
                  "scheduled_at": "2026-10-12 14:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 13:20:11"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/recurrence": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "patch": {
        "tags": [
          "Recurrence"
        ],
        "summary": "Set post recurrence",
        "operationId": "setPostRecurrence",
        "description": "Makes a scheduled post repeat: every `interval` `frequency`, `times` more times after this one. Each occurrence keeps the same local time in the channel's time zone. The post must be `scheduled` with a time, else `422` on `post`: `Only scheduled posts can repeat.` The last occurrence must be before 2038 in every channel's time zone, else `422` on `times`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "interval",
                  "frequency",
                  "times"
                ],
                "properties": {
                  "interval": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 365,
                    "description": "Repeat every N `frequency` units."
                  },
                  "frequency": {
                    "type": "string",
                    "enum": [
                      "day",
                      "week",
                      "month",
                      "year"
                    ]
                  },
                  "times": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "description": "How many times it repeats after this occurrence."
                  }
                }
              },
              "example": {
                "interval": 1,
                "frequency": "week",
                "times": 4
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The post with its repeat rule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "custom",
                  "scheduled_at": "2026-10-12 14:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": {
                    "interval": 1,
                    "frequency": "week",
                    "remaining": 4
                  },
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 13:20:11"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Recurrence"
        ],
        "summary": "Remove post recurrence",
        "operationId": "removePostRecurrence",
        "description": "Stops a post from repeating. The post and its next scheduled time stay.",
        "responses": {
          "200": {
            "description": "The post without a repeat rule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "custom",
                  "scheduled_at": "2026-10-12 14:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 13:20:11"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/media": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "post": {
        "tags": [
          "Media and uploads"
        ],
        "summary": "Upload media",
        "operationId": "uploadPostMedia",
        "description": "Uploads one file as `multipart/form-data` and appends it to the post's media. Accepted files: JPEG, PNG, GIF and WebP images (HEIC and HEIF too when the server can convert them, stored as JPEG), MP4 and MOV videos, and PDF documents. Size caps: 10 MB per image (and at most about 67 megapixels, 8192 × 8192 pixels in total), 1 GB per video, 100 MB per PDF. Each network enforces its own, usually smaller, caps when the post is scheduled or published (`GET /content-types`). A type the post's channel does not accept fails with `422`: `This file type is not supported by the post's channel.` Posts that are publishing, published, partially published or failed cannot take media: `422` on `post` with `This post has already been processed and cannot be re-published. Duplicate it to try again.` On Pinterest and TikTok the content type is chosen again from the post's media, as on create.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "media"
                ],
                "properties": {
                  "media": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The post with the new media.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "custom",
                  "scheduled_at": "2026-10-12 14:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 13:20:11"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/media/from-upload": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "post": {
        "tags": [
          "Media and uploads"
        ],
        "summary": "Attach media from upload",
        "operationId": "attachMediaFromUpload",
        "description": "Appends a file uploaded earlier (`POST /uploads` or a signed upload URL) to the post's media. The token is spent by this post. An unknown or expired token fails with `422` on `upload_token`: `This upload expired. Add the file again.` A type the post's channel does not accept fails with `422`. Posts that are publishing, published, partially published or failed cannot take media: `422` on `post` with `This post has already been processed and cannot be re-published. Duplicate it to try again.` On Pinterest and TikTok the content type is chosen again from the post's media, as on create.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "upload_token"
                ],
                "properties": {
                  "upload_token": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "alt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2000,
                    "description": "Alt text. Applies to images only."
                  }
                }
              },
              "example": {
                "upload_token": "4f6c2b1e-8d3a-4e5f-9a7b-1c2d3e4f5a6b",
                "alt": "Product launch banner"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The post with the new media.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "custom",
                  "scheduled_at": "2026-10-12 14:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 13:20:11"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/posts/{post}/media/from-url": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PostId"
        }
      ],
      "post": {
        "tags": [
          "Media and uploads"
        ],
        "summary": "Attach media from URL",
        "operationId": "attachMediaFromUrl",
        "description": "Downloads up to 10 public files and appends them to the post's media. Each URL must serve the file itself: redirects are not followed, and web pages, private-network hosts and files over the type's size cap are refused. Each download must finish within 20 seconds. Only the types the post's channel accepts are kept. URLs that could not be attached are listed in `failed_urls`, and `failures` gives the reason of each. Posts that are publishing, published, partially published or failed cannot take media: when a file was downloaded, the request fails with `422` on `post` with `This post has already been processed and cannot be re-published. Duplicate it to try again.` Accepted files: JPEG, PNG, GIF and WebP images (HEIC and HEIF too when the server can convert them, stored as JPEG), MP4 and MOV videos, and PDF documents. Size caps: 10 MB per image (and at most about 67 megapixels, 8192 × 8192 pixels in total), 1 GB per video, 100 MB per PDF. Each network enforces its own, usually smaller, caps when the post is scheduled or published (`GET /content-types`). On Pinterest and TikTok the content type is chosen again from the post's media, as on create.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "urls"
                ],
                "properties": {
                  "urls": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10,
                    "items": {
                      "type": "object",
                      "required": [
                        "url"
                      ],
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri",
                          "description": "Public `http` or `https` URL whose host resolves."
                        },
                        "alt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "maxLength": 2000,
                          "description": "Alt text. Applies to images only."
                        }
                      }
                    }
                  }
                }
              },
              "example": {
                "urls": [
                  {
                    "url": "https://example.com/launch.jpg",
                    "alt": "Product launch banner"
                  },
                  {
                    "url": "https://example.com/teaser.mp4"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The post and the result of each URL.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "post": {
                      "$ref": "#/components/schemas/Post"
                    },
                    "attached_count": {
                      "type": "integer"
                    },
                    "failed_urls": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "failures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "url": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string",
                            "enum": [
                              "unreachable",
                              "type_not_allowed",
                              "too_large",
                              "host_not_allowed"
                            ]
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "post": {
                    "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                    "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                    "author": {
                      "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                      "name": "Ana Souza"
                    },
                    "content": "We just shipped scheduled threads. Here is how they work.",
                    "media": [
                      {
                        "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                        "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                        "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                        "type": "image",
                        "mime_type": "image/jpeg",
                        "original_filename": "launch.jpg",
                        "size": 482113,
                        "meta": {
                          "width": 1080,
                          "height": 1350,
                          "alt_text": "Product launch banner"
                        }
                      }
                    ],
                    "status": "scheduled",
                    "schedule_mode": "custom",
                    "scheduled_at": "2026-10-12 14:00:00",
                    "published_at": null,
                    "approval_requested_by": null,
                    "approval_requested_at": null,
                    "approved_by": null,
                    "approved_at": null,
                    "recurrence": null,
                    "origin": "trypost",
                    "platforms": [
                      {
                        "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                        "platform": "x",
                        "content_type": "x_post",
                        "meta": {
                          "thread_replies": [
                            {
                              "text": "2/ Replies publish under the first post.",
                              "media": []
                            }
                          ]
                        },
                        "status": "pending",
                        "enabled": true,
                        "platform_url": null,
                        "published_at": null,
                        "error_message": null,
                        "display_name": "TryPost",
                        "display_username": "trypostit",
                        "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                        "social_account": {
                          "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                          "platform": "x",
                          "display_name": "TryPost",
                          "username": "trypostit",
                          "status": "connected",
                          "has_posting_schedule": true,
                          "timezone": "America/Sao_Paulo",
                          "posting_goal": 5,
                          "max_content_length": 280,
                          "long_posts": false,
                          "verified_badge": null
                        }
                      }
                    ],
                    "labels": [
                      {
                        "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                        "name": "Launch",
                        "color": "#2563EB",
                        "created_at": "2026-09-01 10:00:00",
                        "updated_at": "2026-09-01 10:00:00"
                      }
                    ],
                    "created_at": "2026-10-08 13:20:11",
                    "updated_at": "2026-10-08 13:20:11"
                  },
                  "attached_count": 1,
                  "failed_urls": [
                    "https://example.com/teaser.mp4"
                  ],
                  "failures": [
                    {
                      "url": "https://example.com/teaser.mp4",
                      "reason": "unreachable",
                      "message": "Could not fetch media from https://example.com/teaser.mp4."
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/uploads": {
      "post": {
        "tags": [
          "Media and uploads"
        ],
        "summary": "Create upload",
        "operationId": "createUpload",
        "description": "Uploads one file as `multipart/form-data` without a post and returns an `upload_token`. Pass it as a media item (`media[].upload_token`) to `POST /posts`, `POST /posts/batch` or `PUT /posts/{post}`, or to `POST /posts/{post}/media/from-upload`, before `expires_at`. A token is spent by the first post that takes it; to put the same file on another post, pass that post's `media[].id`. Unused uploads are deleted after 24 hours. Accepted files: JPEG, PNG, GIF and WebP images (HEIC and HEIF too when the server can convert them, stored as JPEG), MP4 and MOV videos, and PDF documents. Size caps: 10 MB per image (and at most about 67 megapixels, 8192 × 8192 pixels in total), 1 GB per video, 100 MB per PDF. Each network enforces its own, usually smaller, caps when the post is scheduled or published (`GET /content-types`).",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "media"
                ],
                "properties": {
                  "media": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The upload.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                },
                "example": {
                  "upload_token": "4f6c2b1e-8d3a-4e5f-9a7b-1c2d3e4f5a6b",
                  "type": "image",
                  "mime_type": "image/jpeg",
                  "size": 482113,
                  "original_filename": "launch.jpg",
                  "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                  "expires_at": "2026-10-09T13:20:11+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/uploads/{token}": {
      "post": {
        "tags": [
          "Media and uploads"
        ],
        "summary": "Upload to signed URL",
        "operationId": "uploadToSignedUrl",
        "security": [],
        "description": "Receives a file at a one-time signed URL issued by the MCP `request-media-upload-tool`. No API key: the signature authorizes the request. Send the file as `multipart/form-data` in the `media` field, for example `curl -F media=@launch.jpg \"<upload_url>\"`. The URL works once, until it expires (15 minutes by default); a second upload to it returns `409`. The returned `upload_token` is then used as a media item, like a token from `POST /uploads`. Accepted files: JPEG, PNG, GIF and WebP images (HEIC and HEIF too when the server can convert them, stored as JPEG), MP4 and MOV videos, and PDF documents. Size caps: 10 MB per image (and at most about 67 megapixels, 8192 × 8192 pixels in total), 1 GB per video, 100 MB per PDF. Each network enforces its own, usually smaller, caps when the post is scheduled or published (`GET /content-types`). A file the server cannot read returns `422` with only `message`: `Unable to read uploaded file.`",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "Upload token from the signed URL.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "4f6c2b1e-8d3a-4e5f-9a7b-1c2d3e4f5a6b"
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": true,
            "description": "Part of the signed URL.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "expires",
            "in": "query",
            "required": true,
            "description": "Part of the signed URL (Unix timestamp).",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "signature",
            "in": "query",
            "required": true,
            "description": "Part of the signed URL.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "media"
                ],
                "properties": {
                  "media": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The stored file.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignedUpload"
                },
                "example": {
                  "upload_token": "4f6c2b1e-8d3a-4e5f-9a7b-1c2d3e4f5a6b",
                  "media_id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                  "type": "image",
                  "mime_type": "image/jpeg",
                  "original_filename": "launch.jpg"
                }
              }
            }
          },
          "403": {
            "description": "The signature is invalid or the URL expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "Invalid signature."
                }
              }
            }
          },
          "404": {
            "description": "The workspace of this URL no longer exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "This URL was already used. The body has an empty `message`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": ""
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "description": "Too many uploads. Limits: 60 per minute per workspace and 1200 per minute per IP address.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/social-accounts": {
      "get": {
        "tags": [
          "Social accounts"
        ],
        "summary": "List social accounts",
        "operationId": "listSocialAccounts",
        "description": "Lists the social accounts (channels) connected to the workspace. Accounts are connected, reconnected and removed in the app; the API cannot change them. `max_content_length` is the text limit of each account (an X account with long posts gets 25000). Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of social accounts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SocialAccount"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                      "platform": "x",
                      "display_name": "TryPost",
                      "username": "trypostit",
                      "status": "connected",
                      "has_posting_schedule": true,
                      "timezone": "America/Sao_Paulo",
                      "posting_goal": 5,
                      "max_content_length": 280,
                      "long_posts": false,
                      "verified_badge": null
                    },
                    {
                      "id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                      "platform": "instagram",
                      "display_name": "TryPost",
                      "username": "trypost.it",
                      "status": "connected",
                      "has_posting_schedule": false,
                      "timezone": "America/Sao_Paulo",
                      "posting_goal": null,
                      "max_content_length": 2200,
                      "long_posts": false,
                      "verified_badge": null
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/social-accounts?page=1",
                    "last": "https://app.trypost.it/api/social-accounts?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/social-accounts?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/social-accounts",
                    "per_page": 25,
                    "to": 2,
                    "total": 2
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/social-accounts/{account}/boards": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "tags": [
          "Social accounts"
        ],
        "summary": "List Pinterest boards",
        "operationId": "listPinterestBoards",
        "description": "Lists the boards of a Pinterest account, read live from Pinterest. Use a board `id` as `meta.board_id` on a Pinterest destination. `truncated` is `true` when TryPost could not read every page of boards from Pinterest. This endpoint also counts against a limit of 60 requests per minute per user, shared with the other Pinterest, Discord and TikTok lookup endpoints and with the same user's channel lookups in the TryPost app.",
        "responses": {
          "200": {
            "description": "The account's boards.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "boards": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PinterestBoard"
                      }
                    },
                    "truncated": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "boards": [
                    {
                      "id": "1029854735246987654",
                      "name": "Product updates",
                      "cover_url": "https://i.pinimg.com/400x300/ab/cd/ef/abcdef.jpg"
                    }
                  ],
                  "truncated": false
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key, or the Pinterest connection expired (body: Pinterest's message, or `Access token has expired or been revoked`). Reconnect the account in the app.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "examples": {
                  "invalid_key": {
                    "summary": "Invalid API key",
                    "value": {
                      "message": "Token not found."
                    }
                  },
                  "pinterest_expired": {
                    "summary": "Pinterest connection expired",
                    "value": {
                      "message": "Access token has expired or been revoked"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "description": "Pinterest refused the request (missing permission), or the API key may not be used (see the shared 403).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "description": "The account is not a Pinterest account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "Boards are only available for Pinterest accounts."
                }
              }
            }
          },
          "429": {
            "description": "Our rate limit was exceeded (`rate_limit_exceeded` body, `Retry-After` set), or Pinterest reports a rate limit (`{message}` body, no `Retry-After`).",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying. Only for our own limit.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RateLimitErrorBody"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorBody"
                    }
                  ]
                }
              }
            }
          },
          "502": {
            "description": "Pinterest answered with an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Pinterest could not be reached (timeout), or another token refresh of this account was running.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "Server Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Social accounts"
        ],
        "summary": "Create Pinterest board",
        "operationId": "createPinterestBoard",
        "description": "Creates a board on a Pinterest account. The name is trimmed. When Pinterest refuses (expired connection, permission, limit or any other error), the request returns `422` with the reason on `name`. This endpoint also counts against a limit of 60 requests per minute per user, shared with the other Pinterest, Discord and TikTok lookup endpoints and with the same user's channel lookups in the TryPost app.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 50,
                    "description": "Board name, at most 50 characters (Pinterest's limit)."
                  }
                }
              },
              "example": {
                "name": "Launch week"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created board.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PinterestBoard"
                },
                "example": {
                  "id": "1029854735246987655",
                  "name": "Launch week",
                  "cover_url": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "The account does not exist in this workspace or is not a Pinterest account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/social-accounts/{account}/channels": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "tags": [
          "Social accounts"
        ],
        "summary": "List Discord channels",
        "operationId": "listDiscordChannels",
        "description": "Lists the channels of a Discord account's server that TryPost's bot can post in, read from Discord and kept for 5 minutes per server. Use a channel `id` as `meta.channel_id` on a Discord destination. This endpoint also counts against a limit of 60 requests per minute per user, shared with the other Pinterest, Discord and TikTok lookup endpoints and with the same user's channel lookups in the TryPost app.",
        "responses": {
          "200": {
            "description": "The server's channels.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "channels": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DiscordChannel"
                      }
                    }
                  }
                },
                "example": {
                  "channels": [
                    {
                      "id": "1123456789012345678",
                      "name": "announcements"
                    },
                    {
                      "id": "1123456789012345679",
                      "name": "general"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "description": "The account is not a Discord account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "Channels are only available for Discord accounts."
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "502": {
            "description": "Discord did not answer as expected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "Discord channel lookup failed (503)."
                }
              }
            }
          },
          "500": {
            "description": "Discord could not be reached (timeout).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "Server Error"
                }
              }
            }
          }
        }
      }
    },
    "/social-accounts/{account}/tiktok-creator-info": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "tags": [
          "Social accounts"
        ],
        "summary": "Get TikTok creator info",
        "operationId": "getTikTokCreatorInfo",
        "description": "Reads what TikTok allows this creator to publish now: the privacy levels to offer as `meta.privacy_level`, whether comments, duets and stitches are off, and the longest video allowed. A creator TikTok does not let post right now comes back with `can_post: false`. Successful answers are kept for 5 minutes. This endpoint also counts against a limit of 60 requests per minute per user, shared with the other Pinterest, Discord and TikTok lookup endpoints and with the same user's channel lookups in the TryPost app.",
        "responses": {
          "200": {
            "description": "The creator's publishing options.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TikTokCreatorInfo"
                },
                "example": {
                  "can_post": true,
                  "privacy_level_options": [
                    "PUBLIC_TO_EVERYONE",
                    "MUTUAL_FOLLOW_FRIENDS",
                    "SELF_ONLY"
                  ],
                  "comment_disabled": false,
                  "duet_disabled": false,
                  "stitch_disabled": true,
                  "max_video_post_duration_sec": 600,
                  "creator_nickname": "TryPost",
                  "creator_username": "trypost.it",
                  "creator_avatar_url": "https://p16-sign.tiktokcdn.com/avatar.jpeg"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "description": "The account is not a TikTok account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "Creator info is only available for TikTok accounts."
                }
              }
            }
          },
          "429": {
            "description": "Our rate limit was exceeded, or TikTok reports a limit (daily post cap, quota or rate limit). For a TikTok limit, `Retry-After` is set when TikTok says when it lifts.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/RateLimitErrorBody"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorBody"
                    }
                  ]
                }
              }
            }
          },
          "502": {
            "description": "TikTok answered with an error, or a refresh of this account's TikTok token is already running (`A TikTok token refresh is already in progress.`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "TikTok didn't answer. Try again in a moment."
                }
              }
            }
          },
          "503": {
            "description": "TikTok did not answer in time.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "TikTok didn't answer. Try again in a moment."
                }
              }
            }
          },
          "500": {
            "description": "The TikTok connection could not be refreshed (for example, no refresh token). Reconnect the account in the app.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                },
                "example": {
                  "message": "Server Error"
                }
              }
            }
          }
        }
      }
    },
    "/channels/{account}/posting-schedule": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "tags": [
          "Channels"
        ],
        "summary": "Get posting schedule",
        "operationId": "getPostingSchedule",
        "description": "Returns the channel's time zone, weekly posting goal and posting times. Queue slots (`queue: next|top`, `queue_slot`) come from these times, in the channel's time zone.",
        "responses": {
          "200": {
            "description": "The posting schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelPostingSchedule"
                },
                "example": {
                  "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                  "timezone": "America/Sao_Paulo",
                  "posting_goal": 5,
                  "posting_schedule": [
                    {
                      "day": 0,
                      "enabled": true,
                      "times": []
                    },
                    {
                      "day": 1,
                      "enabled": true,
                      "times": [
                        "09:00"
                      ]
                    },
                    {
                      "day": 2,
                      "enabled": true,
                      "times": [
                        "09:00",
                        "15:00"
                      ]
                    },
                    {
                      "day": 3,
                      "enabled": true,
                      "times": [
                        "12:00"
                      ]
                    },
                    {
                      "day": 4,
                      "enabled": true,
                      "times": [
                        "09:00"
                      ]
                    },
                    {
                      "day": 5,
                      "enabled": true,
                      "times": []
                    },
                    {
                      "day": 6,
                      "enabled": false,
                      "times": []
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "put": {
        "tags": [
          "Channels"
        ],
        "summary": "Update posting schedule",
        "operationId": "updatePostingSchedule",
        "description": "Replaces the channel's time zone, posting goal and posting times. Send all seven days, or `posting_schedule: null` to remove every posting time. Every field is written: omitting `posting_goal` or `posting_schedule` clears it like `null`, so send the current values to keep them (read them with `GET /channels/{account}/posting-schedule`). Without posting times, the channel's queued posts become custom-time posts at their current time. Queued posts keep their slot. A schedule change moves only the posts whose slot no longer exists, into the first free slots in order. A time zone change first gives each queued post the slot at the same local time in the new zone, then the first free slots; queue requests pending approval follow the same rule. A queued post with no slot left becomes a custom-time post at its current time. Custom-time posts never move.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "timezone"
                ],
                "properties": {
                  "timezone": {
                    "type": "string",
                    "description": "IANA time zone, for example `America/Sao_Paulo`."
                  },
                  "posting_goal": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 28,
                    "description": "Posts per week. `null` or omitted clears it: send the current value to keep it."
                  },
                  "posting_schedule": {
                    "type": [
                      "array",
                      "null"
                    ],
                    "minItems": 7,
                    "maxItems": 7,
                    "items": {
                      "$ref": "#/components/schemas/PostingDay"
                    },
                    "description": "Exactly seven days, each `day` once. `null` or omitted removes the posting times (queued posts become custom-time posts): send the current values to keep them."
                  }
                }
              },
              "example": {
                "timezone": "America/Sao_Paulo",
                "posting_goal": 5,
                "posting_schedule": [
                  {
                    "day": 0,
                    "enabled": true,
                    "times": []
                  },
                  {
                    "day": 1,
                    "enabled": true,
                    "times": [
                      "09:00"
                    ]
                  },
                  {
                    "day": 2,
                    "enabled": true,
                    "times": [
                      "09:00",
                      "15:00"
                    ]
                  },
                  {
                    "day": 3,
                    "enabled": true,
                    "times": [
                      "12:00"
                    ]
                  },
                  {
                    "day": 4,
                    "enabled": true,
                    "times": [
                      "09:00"
                    ]
                  },
                  {
                    "day": 5,
                    "enabled": true,
                    "times": []
                  },
                  {
                    "day": 6,
                    "enabled": false,
                    "times": []
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The saved posting schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelPostingSchedule"
                },
                "example": {
                  "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                  "timezone": "America/Sao_Paulo",
                  "posting_goal": 5,
                  "posting_schedule": [
                    {
                      "day": 0,
                      "enabled": true,
                      "times": []
                    },
                    {
                      "day": 1,
                      "enabled": true,
                      "times": [
                        "09:00"
                      ]
                    },
                    {
                      "day": 2,
                      "enabled": true,
                      "times": [
                        "09:00",
                        "15:00"
                      ]
                    },
                    {
                      "day": 3,
                      "enabled": true,
                      "times": [
                        "12:00"
                      ]
                    },
                    {
                      "day": 4,
                      "enabled": true,
                      "times": [
                        "09:00"
                      ]
                    },
                    {
                      "day": 5,
                      "enabled": true,
                      "times": []
                    },
                    {
                      "day": 6,
                      "enabled": false,
                      "times": []
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/channels/{account}/posting-schedule/generate": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "post": {
        "tags": [
          "Channels"
        ],
        "summary": "Generate posting schedule",
        "operationId": "generatePostingSchedule",
        "description": "Replaces the channel's posting times with `goal` times a week at the hours that usually work best on its network (minutes are randomized), and stores `goal` as the posting goal. Without `goal`, the channel's current goal is used, else 3. The time zone does not change. Every day ends up enabled. `mode` is required but has no effect today: both values generate the same schedule. Queued posts keep their slot. A schedule change moves only the posts whose slot no longer exists, into the first free slots in order. A queued post with no slot left becomes a custom-time post at its current time. Custom-time posts never move.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "goal",
                      "recommended"
                    ],
                    "description": "Required. Currently ignored."
                  },
                  "goal": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 28,
                    "description": "Posts per week."
                  }
                }
              },
              "example": {
                "mode": "goal",
                "goal": 5
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The generated posting schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelPostingSchedule"
                },
                "example": {
                  "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                  "timezone": "America/Sao_Paulo",
                  "posting_goal": 5,
                  "posting_schedule": [
                    {
                      "day": 0,
                      "enabled": true,
                      "times": []
                    },
                    {
                      "day": 1,
                      "enabled": true,
                      "times": [
                        "18:51"
                      ]
                    },
                    {
                      "day": 2,
                      "enabled": true,
                      "times": [
                        "09:14"
                      ]
                    },
                    {
                      "day": 3,
                      "enabled": true,
                      "times": [
                        "12:37"
                      ]
                    },
                    {
                      "day": 4,
                      "enabled": true,
                      "times": [
                        "15:02"
                      ]
                    },
                    {
                      "day": 5,
                      "enabled": true,
                      "times": [
                        "09:40"
                      ]
                    },
                    {
                      "day": 6,
                      "enabled": true,
                      "times": []
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/channels/{account}/posting-schedule/copy": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "post": {
        "tags": [
          "Channels"
        ],
        "summary": "Copy posting schedule",
        "operationId": "copyPostingSchedule",
        "description": "Copies the posting times of another channel of the workspace onto this one. The time zone and posting goal of this channel stay. A source whose `posting_schedule` is `null` returns `422` on `from`. A source with an empty schedule is copied as is, which removes this channel's posting times. Queued posts keep their slot. A schedule change moves only the posts whose slot no longer exists, into the first free slots in order. A queued post with no slot left becomes a custom-time post at its current time. Custom-time posts never move.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "from"
                ],
                "properties": {
                  "from": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Social account to copy from."
                  }
                }
              },
              "example": {
                "from": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The copied posting schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelPostingSchedule"
                },
                "example": {
                  "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                  "timezone": "America/Sao_Paulo",
                  "posting_goal": 5,
                  "posting_schedule": [
                    {
                      "day": 0,
                      "enabled": true,
                      "times": []
                    },
                    {
                      "day": 1,
                      "enabled": true,
                      "times": [
                        "09:00"
                      ]
                    },
                    {
                      "day": 2,
                      "enabled": true,
                      "times": [
                        "09:00",
                        "15:00"
                      ]
                    },
                    {
                      "day": 3,
                      "enabled": true,
                      "times": [
                        "12:00"
                      ]
                    },
                    {
                      "day": 4,
                      "enabled": true,
                      "times": [
                        "09:00"
                      ]
                    },
                    {
                      "day": 5,
                      "enabled": true,
                      "times": []
                    },
                    {
                      "day": 6,
                      "enabled": false,
                      "times": []
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "This channel or the `from` channel does not exist in this workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/channels/{account}/queue/slots": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "tags": [
          "Channels"
        ],
        "summary": "List free queue slots",
        "operationId": "listFreeQueueSlots",
        "description": "Lists the channel's next free queue slots, soonest first: at most 30, within the next 90 days, and more than a minute away. A slot is taken when a scheduled post (queued or custom time) or a queue request pending approval holds it. Pass one as `queue_slot` on `POST /posts` or as `slot_at` on `PUT /channels/{account}/queue/slot`. Empty when the channel has no posting times.",
        "responses": {
          "200": {
            "description": "Free slots as UTC instants.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "slots": {
                      "type": "array",
                      "maxItems": 30,
                      "items": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO 8601, UTC (`Z`)."
                      }
                    }
                  }
                },
                "example": {
                  "slots": [
                    "2026-10-09T12:00:00Z",
                    "2026-10-12T12:00:00Z",
                    "2026-10-13T12:00:00Z"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/channels/{account}/queue/order": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "put": {
        "tags": [
          "Channels"
        ],
        "summary": "Reorder queue",
        "operationId": "reorderQueue",
        "description": "Reorders the first queued posts of the channel. Send the ids of the first N queued posts (scheduled in queue mode, more than a minute away, in time order) in the new order: the posts swap among the times they already hold, and the posts after the first N stay where they are. When the ids are not exactly those first N posts (the queue changed), the request returns `422` on `post_ids`. Custom-time posts are not part of the queue.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "post_ids"
                ],
                "properties": {
                  "post_ids": {
                    "type": "array",
                    "maxItems": 500,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1
                  }
                }
              },
              "example": {
                "post_ids": [
                  "9d3c1f40-7c8d-4e9f-8a0b-1c2d3e4f5a6b",
                  "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41"
                ]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Reordered."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/channels/{account}/queue/slot": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "put": {
        "tags": [
          "Channels"
        ],
        "summary": "Move post to queue slot",
        "operationId": "movePostToQueueSlot",
        "description": "Moves a scheduled post of this channel (queued or custom time) onto one of the channel's free slots, as a queued post. Take `slot_at` from `GET /channels/{account}/queue/slots`. A slot that is taken, not in the posting schedule, more than 90 days away or held by a pending request returns `422` on `slot_at`; so does a post that is not scheduled on this channel. A post created for several channels at once (before TryPost 2.0) cannot be queued: `422` on `queue`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "post_id",
                  "slot_at"
                ],
                "properties": {
                  "post_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "slot_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "The slot, as returned by the slots endpoint."
                  }
                }
              },
              "example": {
                "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                "slot_at": "2026-10-13T12:00:00Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The moved post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                },
                "example": {
                  "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                  "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
                  "author": {
                    "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                    "name": "Ana Souza"
                  },
                  "content": "We just shipped scheduled threads. Here is how they work.",
                  "media": [
                    {
                      "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                      "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "launch.jpg",
                      "size": 482113,
                      "meta": {
                        "width": 1080,
                        "height": 1350,
                        "alt_text": "Product launch banner"
                      }
                    }
                  ],
                  "status": "scheduled",
                  "schedule_mode": "queue",
                  "scheduled_at": "2026-10-13 12:00:00",
                  "published_at": null,
                  "approval_requested_by": null,
                  "approval_requested_at": null,
                  "approved_by": null,
                  "approved_at": null,
                  "recurrence": null,
                  "origin": "trypost",
                  "platforms": [
                    {
                      "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                      "platform": "x",
                      "content_type": "x_post",
                      "meta": {
                        "thread_replies": [
                          {
                            "text": "2/ Replies publish under the first post.",
                            "media": []
                          }
                        ]
                      },
                      "status": "pending",
                      "enabled": true,
                      "platform_url": null,
                      "published_at": null,
                      "error_message": null,
                      "display_name": "TryPost",
                      "display_username": "trypostit",
                      "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "social_account": {
                        "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "display_name": "TryPost",
                        "username": "trypostit",
                        "status": "connected",
                        "has_posting_schedule": true,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": 5,
                        "max_content_length": 280,
                        "long_posts": false,
                        "verified_badge": null
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 13:20:11",
                  "updated_at": "2026-10-08 15:02:40"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/ideas": {
      "get": {
        "tags": [
          "Ideas"
        ],
        "summary": "List ideas",
        "operationId": "listIdeas",
        "description": "Lists the workspace's ideas, newest first, with their media and labels. Stage filters (`stages[]`, `unassigned`) match ideas in any of them; label filters (`labels[]`, `untagged`) work the same way; the two groups combine with AND. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "stages[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only ideas in these stages. Values that are not UUIDs are ignored. Must be sent as a list (`stages[]=…`); a single value without `[]` returns `422`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          {
            "name": "unassigned",
            "in": "query",
            "required": false,
            "description": "Also (or only) ideas without a stage. `true`, `1`, `yes` or `on` turn it on; any other value is off.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "labels[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only ideas with any of these labels. Values that are not UUIDs are ignored. Must be sent as a list (`stages[]=…`); a single value without `[]` returns `422`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          {
            "name": "untagged",
            "in": "query",
            "required": false,
            "description": "Also (or only) ideas without labels. `true`, `1`, `yes` or `on` turn it on; any other value is off.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of ideas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Idea"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9e2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                      "idea_stage_id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                      "title": "Behind the scenes of the 2.0 launch",
                      "body": "Show the team, the whiteboard and the first sketch of the new composer.",
                      "position": 0,
                      "media": [
                        {
                          "id": "9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                          "path": "medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                          "url": "https://media.trypost.it/medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                          "type": "image",
                          "mime_type": "image/jpeg",
                          "original_filename": "whiteboard.jpg",
                          "size": 351204,
                          "meta": {
                            "width": 1600,
                            "height": 1200
                          }
                        }
                      ],
                      "labels": [
                        {
                          "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                          "name": "Launch",
                          "color": "#2563EB",
                          "created_at": "2026-09-01 10:00:00",
                          "updated_at": "2026-09-01 10:00:00"
                        }
                      ],
                      "created_at": "2026-10-07 18:20:00",
                      "updated_at": "2026-10-07 18:20:00"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/ideas?page=1",
                    "last": "https://app.trypost.it/api/ideas?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/ideas?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/ideas",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Ideas"
        ],
        "summary": "Create idea",
        "operationId": "createIdea",
        "description": "Creates an idea at the end of its stage. It needs a title, a body or media: an empty idea returns `422` on `title`. Ideas cannot be turned into posts through the API.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "body": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 10000
                  },
                  "idea_stage_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Stage of this workspace. `null` is Unassigned."
                  },
                  "media_ids": {
                    "type": "array",
                    "maxItems": 10,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Media to attach, by id: the `id` of a media item of a post or idea of this workspace, or the `media_id` of a signed upload. A file taken from a post or idea is copied with a new id; an unclaimed signed upload is attached as is and keeps its id."
                  },
                  "label_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Labels of this workspace."
                  }
                }
              },
              "example": {
                "title": "Behind the scenes of the 2.0 launch",
                "body": "Show the team, the whiteboard and the first sketch of the new composer.",
                "idea_stage_id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                "media_ids": [
                  "9d3c1f31-9b0c-4d1e-8f2a-3b4c5d6e7f80"
                ],
                "label_ids": [
                  "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created idea.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Idea"
                },
                "example": {
                  "id": "9e2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                  "idea_stage_id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                  "title": "Behind the scenes of the 2.0 launch",
                  "body": "Show the team, the whiteboard and the first sketch of the new composer.",
                  "position": 0,
                  "media": [
                    {
                      "id": "9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                      "path": "medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                      "url": "https://media.trypost.it/medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "whiteboard.jpg",
                      "size": 351204,
                      "meta": {
                        "width": 1600,
                        "height": 1200
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-07 18:20:00",
                  "updated_at": "2026-10-07 18:20:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Ideas"
        ],
        "summary": "Delete ideas",
        "operationId": "deleteIdeas",
        "description": "Deletes several ideas and their media. Ids that are not ideas of this workspace are ignored.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "idea_ids"
                ],
                "properties": {
                  "idea_ids": {
                    "type": "array",
                    "maxItems": 500,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1
                  }
                }
              },
              "example": {
                "idea_ids": [
                  "9e2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                  "9e2b3c4e-6f7a-4b8c-9d0e-1f2a3b4c5d6e"
                ]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/ideas/{idea}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/IdeaId"
        }
      ],
      "get": {
        "tags": [
          "Ideas"
        ],
        "summary": "Get idea",
        "operationId": "getIdea",
        "description": "Returns one idea with its media and labels.",
        "responses": {
          "200": {
            "description": "The idea.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Idea"
                },
                "example": {
                  "id": "9e2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                  "idea_stage_id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                  "title": "Behind the scenes of the 2.0 launch",
                  "body": "Show the team, the whiteboard and the first sketch of the new composer.",
                  "position": 0,
                  "media": [
                    {
                      "id": "9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                      "path": "medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                      "url": "https://media.trypost.it/medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "whiteboard.jpg",
                      "size": 351204,
                      "meta": {
                        "width": 1600,
                        "height": 1200
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-07 18:20:00",
                  "updated_at": "2026-10-07 18:20:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "put": {
        "tags": [
          "Ideas"
        ],
        "summary": "Update idea",
        "operationId": "updateIdea",
        "description": "Changes only the fields you send. `media_ids` and `label_ids` replace the whole list. Moving the idea to another stage with `idea_stage_id` puts it at the end of that stage. The idea must keep a title, a body or media.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "body": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 10000
                  },
                  "idea_stage_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Stage of this workspace. `null` is Unassigned."
                  },
                  "media_ids": {
                    "type": "array",
                    "maxItems": 10,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Media to attach, by id: the `id` of a media item of a post or idea of this workspace, or the `media_id` of a signed upload. A file taken from a post or idea is copied with a new id; an unclaimed signed upload is attached as is and keeps its id."
                  },
                  "label_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Labels of this workspace."
                  }
                }
              },
              "example": {
                "title": "Behind the scenes of launch week"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated idea.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Idea"
                },
                "example": {
                  "id": "9e2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                  "idea_stage_id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                  "title": "Behind the scenes of launch week",
                  "body": "Show the team, the whiteboard and the first sketch of the new composer.",
                  "position": 0,
                  "media": [
                    {
                      "id": "9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                      "path": "medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                      "url": "https://media.trypost.it/medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "whiteboard.jpg",
                      "size": 351204,
                      "meta": {
                        "width": 1600,
                        "height": 1200
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-07 18:20:00",
                  "updated_at": "2026-10-08 09:30:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Ideas"
        ],
        "summary": "Delete idea",
        "operationId": "deleteIdea",
        "description": "Deletes one idea and its media.",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/ideas/{idea}/duplicate": {
      "parameters": [
        {
          "$ref": "#/components/parameters/IdeaId"
        }
      ],
      "post": {
        "tags": [
          "Ideas"
        ],
        "summary": "Duplicate idea",
        "operationId": "duplicateIdea",
        "description": "Copies an idea right after the original in the same stage, with its own copy of the media and the same labels.",
        "responses": {
          "201": {
            "description": "The copy.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Idea"
                },
                "example": {
                  "id": "9e2b3c4e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                  "idea_stage_id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                  "title": "Behind the scenes of the 2.0 launch",
                  "body": "Show the team, the whiteboard and the first sketch of the new composer.",
                  "position": 1,
                  "media": [
                    {
                      "id": "9e2b3c51-8b9c-4d0e-9f1a-2b3c4d5e6f70",
                      "path": "medias/9e2b3c51-8b9c-4d0e-9f1a-2b3c4d5e6f70.jpg",
                      "url": "https://media.trypost.it/medias/9e2b3c51-8b9c-4d0e-9f1a-2b3c4d5e6f70.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "whiteboard.jpg",
                      "size": 351204,
                      "meta": {
                        "width": 1600,
                        "height": 1200
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-08 09:30:00",
                  "updated_at": "2026-10-08 09:30:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/ideas/{idea}/move": {
      "parameters": [
        {
          "$ref": "#/components/parameters/IdeaId"
        }
      ],
      "put": {
        "tags": [
          "Ideas"
        ],
        "summary": "Move idea",
        "operationId": "moveIdea",
        "description": "Moves an idea to a stage (or to Unassigned with `idea_stage_id: null`) and sets the order of that stage. `idea_ids` is the full order of the target stage after the move: every idea already in it plus the moved idea, each once. When the list does not match the ideas in that stage (someone changed the board), the request returns `422` on `idea_ids` and nothing moves.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "idea_ids"
                ],
                "properties": {
                  "idea_stage_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Target stage. `null` or omitted is Unassigned."
                  },
                  "idea_ids": {
                    "type": "array",
                    "maxItems": 500,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Full order of the target stage, including the moved idea.",
                    "minItems": 1
                  }
                }
              },
              "example": {
                "idea_stage_id": "9e1a2b3d-5e6f-4a7b-9c8d-0e1f2a3b4c5d",
                "idea_ids": [
                  "9e2b3c4f-7a8b-4c9d-8e0f-2a3b4c5d6e7f",
                  "9e2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The moved idea.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Idea"
                },
                "example": {
                  "id": "9e2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                  "idea_stage_id": "9e1a2b3d-5e6f-4a7b-9c8d-0e1f2a3b4c5d",
                  "title": "Behind the scenes of the 2.0 launch",
                  "body": "Show the team, the whiteboard and the first sketch of the new composer.",
                  "position": 1,
                  "media": [
                    {
                      "id": "9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                      "path": "medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                      "url": "https://media.trypost.it/medias/9e2b3c50-7a8b-4c9d-8e0f-1a2b3c4d5e6f.jpg",
                      "type": "image",
                      "mime_type": "image/jpeg",
                      "original_filename": "whiteboard.jpg",
                      "size": 351204,
                      "meta": {
                        "width": 1600,
                        "height": 1200
                      }
                    }
                  ],
                  "labels": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "created_at": "2026-10-07 18:20:00",
                  "updated_at": "2026-10-07 18:20:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/idea-stages": {
      "get": {
        "tags": [
          "Idea stages"
        ],
        "summary": "List idea stages",
        "operationId": "listIdeaStages",
        "description": "Lists every stage (column) of the ideas board in board order, with `ideas_count`. Not paginated: the body is a plain array.",
        "responses": {
          "200": {
            "description": "The stages.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/IdeaStage"
                  }
                },
                "example": [
                  {
                    "id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                    "name": "To write",
                    "position": 0,
                    "ideas_count": 4,
                    "created_at": "2026-09-20 12:00:00",
                    "updated_at": "2026-09-20 12:00:00"
                  },
                  {
                    "id": "9e1a2b3d-5e6f-4a7b-9c8d-0e1f2a3b4c5d",
                    "name": "Ready",
                    "position": 1,
                    "ideas_count": 1,
                    "created_at": "2026-09-20 12:00:00",
                    "updated_at": "2026-09-20 12:00:00"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Idea stages"
        ],
        "summary": "Create idea stage",
        "operationId": "createIdeaStage",
        "description": "Adds a stage at the end of the board.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 60
                  }
                }
              },
              "example": {
                "name": "Ready"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created stage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdeaStage"
                },
                "example": {
                  "id": "9e1a2b3d-5e6f-4a7b-9c8d-0e1f2a3b4c5d",
                  "name": "Ready",
                  "position": 1,
                  "created_at": "2026-09-20 12:00:00",
                  "updated_at": "2026-09-20 12:00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/idea-stages/order": {
      "put": {
        "tags": [
          "Idea stages"
        ],
        "summary": "Reorder idea stages",
        "operationId": "reorderIdeaStages",
        "description": "Sets the board order. Send the ids of every stage of the workspace, each once, in the new order. A list that does not match the current stages returns `422` on `stage_ids`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "stage_ids"
                ],
                "properties": {
                  "stage_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1
                  }
                }
              },
              "example": {
                "stage_ids": [
                  "9e1a2b3d-5e6f-4a7b-9c8d-0e1f2a3b4c5d",
                  "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Every stage in the new order (a plain array).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/IdeaStage"
                  }
                },
                "example": [
                  {
                    "id": "9e1a2b3d-5e6f-4a7b-9c8d-0e1f2a3b4c5d",
                    "name": "Ready",
                    "position": 0,
                    "ideas_count": 1,
                    "created_at": "2026-09-20 12:00:00",
                    "updated_at": "2026-09-20 12:00:00"
                  },
                  {
                    "id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                    "name": "To write",
                    "position": 1,
                    "ideas_count": 4,
                    "created_at": "2026-09-20 12:00:00",
                    "updated_at": "2026-09-20 12:00:00"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/idea-stages/{ideaStage}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/IdeaStageId"
        }
      ],
      "put": {
        "tags": [
          "Idea stages"
        ],
        "summary": "Update idea stage",
        "operationId": "updateIdeaStage",
        "description": "Renames a stage.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 60
                  }
                }
              },
              "example": {
                "name": "Drafting"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated stage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IdeaStage"
                },
                "example": {
                  "id": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
                  "name": "Drafting",
                  "position": 0,
                  "created_at": "2026-09-20 12:00:00",
                  "updated_at": "2026-10-08 09:30:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Idea stages"
        ],
        "summary": "Delete idea stage",
        "operationId": "deleteIdeaStage",
        "description": "Deletes a stage. Its ideas are not deleted: they move to the end of Unassigned, in their order.",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/analytics": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get workspace analytics",
        "operationId": "getWorkspaceAnalytics",
        "description": "Returns the analytics report of the workspace for a date range, compared with the previous range of the same length: summary, followers, posts per bucket, top posts, per-channel performance and collection coverage. Days are calendar days in the API key user's time zone (Settings → Preferences) and weekly buckets start on that user's start of week. With `custom` (or `start`/`end` without `range`), the dates are clamped to the days with data in scope (`bounds`; for a channel, that channel's). When there is no data yet, the dates are ignored and the last 30 days are returned. A missing `end` defaults to the last day with data, and a missing `start` to 29 days before `end`. Read `range` (or `filters.start`/`filters.end`) in the response for the days actually used. The report reads analytics TryPost has already collected from the networks, not live data. LinkedIn, LinkedIn pages, Telegram, Discord and Google Business are not included.",
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "`7d` (last 7 days), `30d` (last 30 days, the default), `mtd` (month to date) or `custom`. Days are calendar days in the API key user's time zone, today included.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "mtd",
                "custom"
              ],
              "default": "30d"
            }
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "description": "First day, `Y-m-d`. Required with `range=custom` and ignored for the other presets. Sending `start` and `end` without `range` means `custom`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "description": "Last day, `Y-m-d`, on or after `start`. Required with `range=custom`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "channels[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only these social accounts. Unknown ids and accounts without analytics are ignored without an error; when none of the ids is usable, the report covers every channel.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uuid"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The report.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceAnalyticsReport"
                },
                "example": {
                  "bounds": {
                    "min": "2026-04-11",
                    "max": "2026-10-08"
                  },
                  "range": {
                    "start": "2026-10-02",
                    "end": "2026-10-08"
                  },
                  "previous_range": {
                    "start": "2026-09-25",
                    "end": "2026-10-01"
                  },
                  "summary": {
                    "posts": {
                      "value": 18,
                      "previous": 15,
                      "change": 20.0
                    },
                    "followers": {
                      "value": 12480,
                      "previous": 12160,
                      "change": 320
                    },
                    "net_followers": {
                      "value": 320,
                      "previous": 250,
                      "change": 28.0
                    },
                    "reactions": {
                      "value": 2140,
                      "previous": 1890,
                      "change": 13.23
                    },
                    "comments": {
                      "value": 188,
                      "previous": 205,
                      "change": -8.29
                    },
                    "engagement_rate": {
                      "value": 4.12,
                      "previous": 3.85,
                      "change": 7.01
                    },
                    "views": {
                      "value": 48210,
                      "previous": 39900,
                      "change": 20.83
                    },
                    "impressions": {
                      "value": 61300,
                      "previous": 52010,
                      "change": 17.86
                    },
                    "clicks": {
                      "value": 512,
                      "previous": 430,
                      "change": 19.07
                    },
                    "reposts": {
                      "value": 96,
                      "previous": 80,
                      "change": 20.0
                    },
                    "quotes": {
                      "value": 12,
                      "previous": 9,
                      "change": 33.33
                    },
                    "reach": {
                      "value": 30120,
                      "previous": 27400,
                      "change": 9.93
                    },
                    "shares": {
                      "value": 140,
                      "previous": 118,
                      "change": 18.64
                    },
                    "saves": {
                      "value": 210,
                      "previous": 175,
                      "change": 20.0
                    },
                    "watch_time_minutes": {
                      "value": 1830.5,
                      "previous": 1502.25,
                      "change": 21.85
                    },
                    "average_watch_time_seconds": {
                      "value": 14.2,
                      "previous": 12.8,
                      "change": 10.94
                    },
                    "follows_gained": {
                      "value": 41,
                      "previous": 37,
                      "change": 10.81
                    }
                  },
                  "followers": {
                    "total": 12480,
                    "accounts": [
                      {
                        "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "social_account_id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "network": "x",
                        "name": "TryPost",
                        "username": "trypostit",
                        "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                        "value": 12480,
                        "growth": 320,
                        "net": 320,
                        "provenance": "provider",
                        "status": "connected"
                      }
                    ],
                    "series": [
                      {
                        "date": "2026-10-02",
                        "accounts": {
                          "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54": 12160
                        }
                      },
                      {
                        "date": "2026-10-08",
                        "accounts": {
                          "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54": 12480
                        }
                      }
                    ]
                  },
                  "posts": {
                    "resolution": "daily",
                    "accounts": [
                      {
                        "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "name": "TryPost",
                        "username": "trypostit",
                        "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                        "count": 18,
                        "status": "connected"
                      }
                    ],
                    "buckets": [
                      {
                        "start": "2026-10-02",
                        "end": "2026-10-02",
                        "accounts": {
                          "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54": 3
                        },
                        "total": 3
                      }
                    ]
                  },
                  "top_posts": {
                    "reactions": [
                      {
                        "id": "9d4a0b1c-2d3e-4f5a-8b6c-7d8e9f0a1b2c",
                        "post_platform_id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                        "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                        "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "name": "TryPost",
                        "username": "trypostit",
                        "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                        "origin": "trypost",
                        "content_type": "image",
                        "availability": "available",
                        "published_at": "2026-10-02 14:00:00",
                        "permalink": "https://x.com/trypostit/status/1841234567890123456",
                        "excerpt": "We just shipped scheduled threads. Here is how they work.",
                        "preview_metadata": null,
                        "reactions": 412,
                        "comments": 38,
                        "status": "connected"
                      }
                    ],
                    "comments": [
                      {
                        "id": "9d4a0b1c-2d3e-4f5a-8b6c-7d8e9f0a1b2c",
                        "post_platform_id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                        "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                        "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "name": "TryPost",
                        "username": "trypostit",
                        "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                        "origin": "trypost",
                        "content_type": "image",
                        "availability": "available",
                        "published_at": "2026-10-02 14:00:00",
                        "permalink": "https://x.com/trypostit/status/1841234567890123456",
                        "excerpt": "We just shipped scheduled threads. Here is how they work.",
                        "preview_metadata": null,
                        "reactions": 412,
                        "comments": 38,
                        "status": "connected"
                      }
                    ]
                  },
                  "performance": [
                    {
                      "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                      "platform": "x",
                      "name": "TryPost",
                      "username": "trypostit",
                      "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                      "posts": {
                        "value": 18,
                        "previous": 15,
                        "change": 20.0
                      },
                      "reactions": {
                        "value": 2140,
                        "previous": 1890,
                        "change": 13.23
                      },
                      "comments": {
                        "value": 188,
                        "previous": 205,
                        "change": -8.29
                      },
                      "engagement_rate": {
                        "value": 4.12,
                        "previous": 3.85,
                        "change": 7.01
                      },
                      "reposts": {
                        "value": 96,
                        "previous": 80,
                        "change": 20.0
                      },
                      "impressions": {
                        "value": 61300,
                        "previous": 52010,
                        "change": 17.86
                      },
                      "clicks": {
                        "value": 512,
                        "previous": 430,
                        "change": 19.07
                      },
                      "views": {
                        "value": 48210,
                        "previous": 39900,
                        "change": 20.83
                      },
                      "shares": {
                        "value": 140,
                        "previous": 118,
                        "change": 18.64
                      },
                      "saves": {
                        "value": 210,
                        "previous": 175,
                        "change": 20.0
                      },
                      "follows_gained": {
                        "value": 41,
                        "previous": 37,
                        "change": 10.81
                      },
                      "reach": {
                        "value": 30120,
                        "previous": 27400,
                        "change": 9.93
                      },
                      "watch_time_minutes": {
                        "value": 1830.5,
                        "previous": 1502.25,
                        "change": 21.85
                      },
                      "average_watch_time_seconds": {
                        "value": 14.2,
                        "previous": 12.8,
                        "change": 10.94
                      },
                      "status": "connected"
                    }
                  ],
                  "coverage": [
                    {
                      "social_account_id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                      "collector": "publication_backfill",
                      "status": "complete",
                      "target_since": "2026-04-11T00:00:00.000000Z",
                      "oldest_reached_at": "2026-04-11T09:12:00.000000Z",
                      "high_watermark_at": "2026-10-08T06:00:00.000000Z",
                      "last_success_at": "2026-10-08T06:00:00.000000Z",
                      "last_error_category": null
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/analytics/publications/{publication}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/PublicationId"
        }
      ],
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get publication analytics",
        "operationId": "getPublicationAnalytics",
        "description": "Returns the latest saved analytics of one publication: a post published through TryPost or found on a connected channel. Take the id from `top_posts` in `GET /analytics` or from `GET /channels/{account}/insights/publications`. A publication deleted on the network or no longer available, of another workspace or of a network without analytics returns `404`.",
        "responses": {
          "200": {
            "description": "The publication's analytics.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicationAnalytics"
                },
                "example": {
                  "available": true,
                  "reason": null,
                  "publication": {
                    "id": "9d4a0b1c-2d3e-4f5a-8b6c-7d8e9f0a1b2c",
                    "post_platform_id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                    "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                    "platform": "x",
                    "origin": "trypost",
                    "content_type": "text",
                    "availability": "available",
                    "provider_published_at": "2026-10-12T14:00:03+00:00",
                    "permalink": "https://x.com/trypostit/status/1843921066571337728",
                    "excerpt": "We just shipped scheduled threads.",
                    "preview_metadata": null,
                    "account_display_name": "TryPost",
                    "account_username": "trypostit",
                    "account_avatar_url": null
                  },
                  "snapshot": {
                    "date": "2026-10-14",
                    "collected_at": "2026-10-14T06:10:00+00:00",
                    "provider_observed_at": "2026-10-14T06:09:58+00:00",
                    "reactions_count": 42,
                    "comments_count": 5,
                    "shares_count": 7,
                    "saves_count": 3,
                    "views_count": null,
                    "impressions_count": 3120,
                    "reach_count": null,
                    "engagement_count": 57,
                    "exposure_count": 3120,
                    "exposure_kind": "impressions",
                    "watch_time_milliseconds": null,
                    "average_watch_time_milliseconds": null
                  },
                  "metrics": {
                    "impressions": {
                      "value": 3120,
                      "unit": "count",
                      "time_basis": "lifetime",
                      "precision": "exact",
                      "availability": "available",
                      "provider_metric": "impression_count",
                      "period_start": null,
                      "period_end": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/channels/{account}/insights": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get channel insights",
        "operationId": "getChannelInsights",
        "description": "Returns the insights of one channel for a date range: the metrics it reports, the summary and the metric series for the range and the previous range. Days are calendar days in the API key user's time zone. Labels, untagged and types narrow the post metrics; followers stay account-wide. Channels on LinkedIn, LinkedIn pages, Telegram, Discord and Google Business have no insights and return `404`. With `custom` (or `start`/`end` without `range`), the dates are clamped to the days with data in scope (`bounds`; for a channel, that channel's). When there is no data yet, the dates are ignored and the last 30 days are returned. A missing `end` defaults to the last day with data, and a missing `start` to 29 days before `end`. Read `range` (or `filters.start`/`filters.end`) in the response for the days actually used.",
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "`7d` (last 7 days), `30d` (last 30 days, the default), `mtd` (month to date) or `custom`. Days are calendar days in the API key user's time zone, today included.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "mtd",
                "custom"
              ],
              "default": "30d"
            }
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "description": "First day, `Y-m-d`. Required with `range=custom` and ignored for the other presets. Sending `start` and `end` without `range` means `custom`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "description": "Last day, `Y-m-d`, on or after `start`. Required with `range=custom`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "labels[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only posts with any of these labels (labels of this workspace). Unknown or deleted labels return `422`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          {
            "name": "untagged",
            "in": "query",
            "required": false,
            "description": "Also (or only) posts without labels. Posts made outside TryPost have no labels. Send `1` or `0`; `true` and `false` are rejected with `422`.",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "0"
              ]
            }
          },
          {
            "name": "types[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only these content types. They must belong to the channel's network.",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/ContentType"
              }
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "Accepted for parity with the post list; only echoed in `filters` here.",
            "schema": {
              "type": "string",
              "enum": [
                "current",
                "previous"
              ],
              "default": "current"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Accepted for parity with the post list; only echoed in `filters` here.",
            "schema": {
              "type": "string",
              "enum": [
                "reactions",
                "comments",
                "engagement_rate",
                "views",
                "impressions",
                "shares",
                "saves",
                "reach"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The channel's insights.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelInsights"
                },
                "example": {
                  "filters": {
                    "range": "30d",
                    "start": "2026-09-09",
                    "end": "2026-10-08",
                    "period": "current",
                    "sort": "reactions",
                    "labels": [],
                    "untagged": false,
                    "types": []
                  },
                  "available_metrics": [
                    "followers",
                    "net_followers",
                    "posts",
                    "reactions",
                    "comments",
                    "engagement_rate",
                    "views",
                    "impressions",
                    "reposts",
                    "quotes",
                    "clicks"
                  ],
                  "summary": {
                    "bounds": {
                      "min": "2026-04-11",
                      "max": "2026-10-08"
                    },
                    "range": {
                      "start": "2026-09-09",
                      "end": "2026-10-08"
                    },
                    "previous_range": {
                      "start": "2026-08-10",
                      "end": "2026-09-08"
                    },
                    "summary": {
                      "posts": {
                        "value": 18,
                        "previous": 15,
                        "change": 20.0
                      },
                      "followers": {
                        "value": 12480,
                        "previous": 12160,
                        "change": 320
                      },
                      "net_followers": {
                        "value": 320,
                        "previous": 250,
                        "change": 28.0
                      },
                      "reactions": {
                        "value": 2140,
                        "previous": 1890,
                        "change": 13.23
                      },
                      "comments": {
                        "value": 188,
                        "previous": 205,
                        "change": -8.29
                      },
                      "engagement_rate": {
                        "value": 4.12,
                        "previous": 3.85,
                        "change": 7.01
                      },
                      "views": {
                        "value": 48210,
                        "previous": 39900,
                        "change": 20.83
                      },
                      "impressions": {
                        "value": 61300,
                        "previous": 52010,
                        "change": 17.86
                      },
                      "clicks": {
                        "value": 512,
                        "previous": 430,
                        "change": 19.07
                      },
                      "reposts": {
                        "value": 96,
                        "previous": 80,
                        "change": 20.0
                      },
                      "quotes": {
                        "value": 12,
                        "previous": 9,
                        "change": 33.33
                      },
                      "reach": {
                        "value": 30120,
                        "previous": 27400,
                        "change": 9.93
                      },
                      "shares": {
                        "value": 140,
                        "previous": 118,
                        "change": 18.64
                      },
                      "saves": {
                        "value": 210,
                        "previous": 175,
                        "change": 20.0
                      },
                      "watch_time_minutes": {
                        "value": 1830.5,
                        "previous": 1502.25,
                        "change": 21.85
                      },
                      "average_watch_time_seconds": {
                        "value": 14.2,
                        "previous": 12.8,
                        "change": 10.94
                      },
                      "follows_gained": {
                        "value": 41,
                        "previous": 37,
                        "change": 10.81
                      }
                    },
                    "followers": {
                      "total": 12480,
                      "accounts": [
                        {
                          "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                          "social_account_id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                          "platform": "x",
                          "network": "x",
                          "name": "TryPost",
                          "username": "trypostit",
                          "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                          "value": 12480,
                          "growth": 320,
                          "net": 320,
                          "provenance": "provider",
                          "status": "connected"
                        }
                      ],
                      "series": [
                        {
                          "date": "2026-10-02",
                          "accounts": {
                            "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54": 12160
                          }
                        },
                        {
                          "date": "2026-10-08",
                          "accounts": {
                            "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54": 12480
                          }
                        }
                      ]
                    },
                    "posts": {
                      "resolution": "weekly",
                      "accounts": [
                        {
                          "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                          "platform": "x",
                          "name": "TryPost",
                          "username": "trypostit",
                          "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                          "count": 18,
                          "status": "connected"
                        }
                      ],
                      "buckets": [
                        {
                          "start": "2026-09-28",
                          "end": "2026-10-04",
                          "accounts": {
                            "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54": 3
                          },
                          "total": 3
                        }
                      ]
                    },
                    "top_posts": {
                      "reactions": [
                        {
                          "id": "9d4a0b1c-2d3e-4f5a-8b6c-7d8e9f0a1b2c",
                          "post_platform_id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                          "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                          "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                          "platform": "x",
                          "name": "TryPost",
                          "username": "trypostit",
                          "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                          "origin": "trypost",
                          "content_type": "image",
                          "availability": "available",
                          "published_at": "2026-10-02 14:00:00",
                          "permalink": "https://x.com/trypostit/status/1841234567890123456",
                          "excerpt": "We just shipped scheduled threads. Here is how they work.",
                          "preview_metadata": null,
                          "reactions": 412,
                          "comments": 38,
                          "status": "connected"
                        }
                      ],
                      "comments": [
                        {
                          "id": "9d4a0b1c-2d3e-4f5a-8b6c-7d8e9f0a1b2c",
                          "post_platform_id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                          "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                          "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                          "platform": "x",
                          "name": "TryPost",
                          "username": "trypostit",
                          "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                          "origin": "trypost",
                          "content_type": "image",
                          "availability": "available",
                          "published_at": "2026-10-02 14:00:00",
                          "permalink": "https://x.com/trypostit/status/1841234567890123456",
                          "excerpt": "We just shipped scheduled threads. Here is how they work.",
                          "preview_metadata": null,
                          "reactions": 412,
                          "comments": 38,
                          "status": "connected"
                        }
                      ]
                    },
                    "performance": [
                      {
                        "social_account_key": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "platform": "x",
                        "name": "TryPost",
                        "username": "trypostit",
                        "avatar_url": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                        "posts": {
                          "value": 18,
                          "previous": 15,
                          "change": 20.0
                        },
                        "reactions": {
                          "value": 2140,
                          "previous": 1890,
                          "change": 13.23
                        },
                        "comments": {
                          "value": 188,
                          "previous": 205,
                          "change": -8.29
                        },
                        "engagement_rate": {
                          "value": 4.12,
                          "previous": 3.85,
                          "change": 7.01
                        },
                        "reposts": {
                          "value": 96,
                          "previous": 80,
                          "change": 20.0
                        },
                        "impressions": {
                          "value": 61300,
                          "previous": 52010,
                          "change": 17.86
                        },
                        "clicks": {
                          "value": 512,
                          "previous": 430,
                          "change": 19.07
                        },
                        "views": {
                          "value": 48210,
                          "previous": 39900,
                          "change": 20.83
                        },
                        "shares": {
                          "value": 140,
                          "previous": 118,
                          "change": 18.64
                        },
                        "saves": {
                          "value": 210,
                          "previous": 175,
                          "change": 20.0
                        },
                        "follows_gained": {
                          "value": 41,
                          "previous": 37,
                          "change": 10.81
                        },
                        "reach": {
                          "value": 30120,
                          "previous": 27400,
                          "change": 9.93
                        },
                        "watch_time_minutes": {
                          "value": 1830.5,
                          "previous": 1502.25,
                          "change": 21.85
                        },
                        "average_watch_time_seconds": {
                          "value": 14.2,
                          "previous": 12.8,
                          "change": 10.94
                        },
                        "status": "connected"
                      }
                    ],
                    "coverage": [
                      {
                        "social_account_id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                        "collector": "publication_backfill",
                        "status": "complete",
                        "target_since": "2026-04-11T00:00:00.000000Z",
                        "oldest_reached_at": "2026-04-11T09:12:00.000000Z",
                        "high_watermark_at": "2026-10-08T06:00:00.000000Z",
                        "last_success_at": "2026-10-08T06:00:00.000000Z",
                        "last_error_category": null
                      }
                    ]
                  },
                  "metric_series": {
                    "resolution": "daily",
                    "metrics": [
                      "posts",
                      "followers",
                      "net_followers",
                      "views",
                      "impressions"
                    ],
                    "range": {
                      "start": "2026-09-09",
                      "end": "2026-10-08"
                    },
                    "previous_range": {
                      "start": "2026-08-10",
                      "end": "2026-09-08"
                    },
                    "current": [
                      {
                        "start": "2026-09-09",
                        "end": "2026-09-09",
                        "values": {
                          "posts": 1,
                          "followers": 12160,
                          "net_followers": 4,
                          "views": 2300,
                          "impressions": 2900
                        }
                      }
                    ],
                    "previous": [
                      {
                        "start": "2026-08-10",
                        "end": "2026-08-10",
                        "values": {
                          "posts": 0,
                          "followers": 11900,
                          "net_followers": 3,
                          "views": 0,
                          "impressions": 0
                        }
                      }
                    ],
                    "totals": {
                      "current": {
                        "posts": 18,
                        "followers": 12480,
                        "net_followers": 320,
                        "views": 48210,
                        "impressions": 61300
                      },
                      "previous": {
                        "posts": 15,
                        "followers": 12160,
                        "net_followers": 250,
                        "views": 39900,
                        "impressions": 52010
                      }
                    },
                    "growth": {
                      "range": {
                        "start": "2025-11-01",
                        "end": "2026-10-08"
                      },
                      "months": [
                        {
                          "month": "2026-10",
                          "start": "2026-10-01",
                          "end": "2026-10-08",
                          "followers": 12480,
                          "rate": 1.4
                        }
                      ],
                      "latest": 1.4,
                      "previous": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/channels/{account}/insights/publications": {
      "parameters": [
        {
          "$ref": "#/components/parameters/AccountId"
        }
      ],
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "List channel post performance",
        "operationId": "listChannelPostPerformance",
        "description": "Ranks the channel's posts of the range (made in TryPost or not) by one metric, best first, and returns the top 50 a page at a time. Page size is set by the server: read `meta.per_page`. The response also carries the `filters` the server applied. Posts without the metric come last. Same time zone, filters, range clamping and `404` rule as `GET /channels/{account}/insights`.",
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "`7d` (last 7 days), `30d` (last 30 days, the default), `mtd` (month to date) or `custom`. Days are calendar days in the API key user's time zone, today included.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "mtd",
                "custom"
              ],
              "default": "30d"
            }
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "description": "First day, `Y-m-d`. Required with `range=custom` and ignored for the other presets. Sending `start` and `end` without `range` means `custom`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "description": "Last day, `Y-m-d`, on or after `start`. Required with `range=custom`.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "labels[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only posts with any of these labels (labels of this workspace). Unknown or deleted labels return `422`.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          {
            "name": "untagged",
            "in": "query",
            "required": false,
            "description": "Also (or only) posts without labels. Posts made outside TryPost have no labels. Send `1` or `0`; `true` and `false` are rejected with `422`.",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "0"
              ]
            }
          },
          {
            "name": "types[]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "description": "Only these content types. They must belong to the channel's network.",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/ContentType"
              }
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "`previous` ranks the posts of the previous range of the same length.",
            "schema": {
              "type": "string",
              "enum": [
                "current",
                "previous"
              ],
              "default": "current"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Metric to rank by. When the channel does not report it (or it is omitted), the first of these the channel reports is used; `filters.sort` says which.",
            "schema": {
              "type": "string",
              "enum": [
                "reactions",
                "comments",
                "engagement_rate",
                "views",
                "impressions",
                "shares",
                "saves",
                "reach"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of ranked posts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ChannelPostPerformance"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    },
                    "filters": {
                      "$ref": "#/components/schemas/ChannelInsightsFilters"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9d4a0b1c-2d3e-4f5a-8b6c-7d8e9f0a1b2c",
                      "rank": 1,
                      "post_id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                      "excerpt": "We just shipped scheduled threads. Here is how they work.",
                      "thumbnail_url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                      "permalink": "https://x.com/trypostit/status/1841234567890123456",
                      "published_at": "2026-10-02T14:00:00+00:00",
                      "content_type": "image",
                      "metrics": {
                        "reactions": 412,
                        "comments": 38,
                        "engagement_rate": 5.31,
                        "views": 9120,
                        "impressions": 10230,
                        "shares": null,
                        "reposts": 41,
                        "quotes": 6,
                        "saves": null,
                        "clicks": 133,
                        "follows_gained": null,
                        "reach": null,
                        "watch_time_minutes": null,
                        "average_watch_time_seconds": null
                      }
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/channels/9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54/insights/publications?page=1",
                    "last": "https://app.trypost.it/api/channels/9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54/insights/publications?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/channels/9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54/insights/publications?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/channels/9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54/insights/publications",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  },
                  "filters": {
                    "range": "30d",
                    "start": "2026-09-09",
                    "end": "2026-10-08",
                    "period": "current",
                    "sort": "reactions",
                    "labels": [],
                    "untagged": false,
                    "types": []
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/labels": {
      "get": {
        "tags": [
          "Labels"
        ],
        "summary": "List labels",
        "operationId": "listLabels",
        "description": "Lists the workspace's labels, newest first. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of labels.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Label"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                      "name": "Launch",
                      "color": "#2563EB",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/labels?page=1",
                    "last": "https://app.trypost.it/api/labels?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/labels?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/labels",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Create label",
        "operationId": "createLabel",
        "description": "Creates a label. Attach it to posts with `label_ids` and to ideas with `label_ids`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "color"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "description": "Hex color, `#RRGGBB`."
                  }
                }
              },
              "example": {
                "name": "Launch",
                "color": "#2563EB"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created label.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Label"
                },
                "example": {
                  "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                  "name": "Launch",
                  "color": "#2563EB",
                  "created_at": "2026-09-01 10:00:00",
                  "updated_at": "2026-09-01 10:00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/labels/{label}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/LabelId"
        }
      ],
      "put": {
        "tags": [
          "Labels"
        ],
        "summary": "Update label",
        "operationId": "updateLabel",
        "description": "Renames a label or changes its color. Send both fields.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "color"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "color": {
                    "type": "string",
                    "pattern": "^#[0-9A-Fa-f]{6}$",
                    "description": "Hex color, `#RRGGBB`."
                  }
                }
              },
              "example": {
                "name": "Launch",
                "color": "#16A34A"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated label.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Label"
                },
                "example": {
                  "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                  "name": "Launch",
                  "color": "#16A34A",
                  "created_at": "2026-09-01 10:00:00",
                  "updated_at": "2026-10-08 09:30:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Labels"
        ],
        "summary": "Delete label",
        "operationId": "deleteLabel",
        "description": "Deletes a label. It no longer shows on posts and ideas.",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/signatures": {
      "get": {
        "tags": [
          "Signatures"
        ],
        "summary": "List signatures",
        "operationId": "listSignatures",
        "description": "Lists the workspace's signatures, newest first. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of signatures.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Signature"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                      "name": "Blog footer",
                      "content": "Read more on our blog: trypost.it/blog",
                      "created_at": "2026-09-01 10:00:00",
                      "updated_at": "2026-09-01 10:00:00"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/signatures?page=1",
                    "last": "https://app.trypost.it/api/signatures?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/signatures?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/signatures",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Signatures"
        ],
        "summary": "Create signature",
        "operationId": "createSignature",
        "description": "Creates a signature: reusable text members can insert in the composer. A signature is never added to posts automatically, including posts created through the API.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "content"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "content": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "name": "Blog footer",
                "content": "Read more on our blog: trypost.it/blog"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created signature.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Signature"
                },
                "example": {
                  "id": "9c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                  "name": "Blog footer",
                  "content": "Read more on our blog: trypost.it/blog",
                  "created_at": "2026-09-01 10:00:00",
                  "updated_at": "2026-09-01 10:00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/signatures/{signature}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/SignatureId"
        }
      ],
      "put": {
        "tags": [
          "Signatures"
        ],
        "summary": "Update signature",
        "operationId": "updateSignature",
        "description": "Changes a signature's name and text. Send both fields.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "content"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "content": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "name": "Blog footer",
                "content": "More on our blog: trypost.it/blog"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated signature.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Signature"
                },
                "example": {
                  "id": "9c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                  "name": "Blog footer",
                  "content": "More on our blog: trypost.it/blog",
                  "created_at": "2026-09-01 10:00:00",
                  "updated_at": "2026-10-08 09:30:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Signatures"
        ],
        "summary": "Delete signature",
        "operationId": "deleteSignature",
        "description": "Deletes a signature. Posts that already contain its text keep it.",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/workspace": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "summary": "Get workspace",
        "operationId": "getWorkspace",
        "description": "Returns the workspace the API key belongs to, and in `me` what the key's user may do there. API keys belong to admins, so `me.is_admin` is `true` and posts sent through the API never wait for approval.",
        "responses": {
          "200": {
            "description": "The workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                },
                "example": {
                  "id": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
                  "name": "TryPost",
                  "created_at": "2026-05-04 12:00:00",
                  "updated_at": "2026-09-30 08:15:00",
                  "me": {
                    "is_admin": true,
                    "requires_approval": false,
                    "publishes_directly": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/api-keys": {
      "get": {
        "tags": [
          "API keys"
        ],
        "summary": "List API keys",
        "operationId": "listApiKeys",
        "description": "Lists your own API keys for this workspace that are not deleted, newest first. Keys of other members are not listed. The secret is never returned again. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of API keys.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ApiKey"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "4f1d8c2b7e9a03c6d5b8e1f2a3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0",
                      "name": "Zapier",
                      "last_used_at": "2026-10-08T13:00:00+00:00",
                      "expires_at": "2026-12-31T23:59:59+00:00",
                      "created_at": "2026-10-08T12:00:00+00:00"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/api-keys?page=1",
                    "last": "https://app.trypost.it/api/api-keys?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/api-keys?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/api-keys",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "API keys"
        ],
        "summary": "Create API key",
        "operationId": "createApiKey",
        "description": "Creates an API key for you in this workspace. `plain_token` is the key: it is shown only in this response, so store it now. With `expires_at`, the key stops working at the end of that day (UTC); without it, it never expires.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "expires_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date",
                    "description": "Last day the key works, today or later."
                  }
                }
              },
              "example": {
                "name": "Zapier",
                "expires_at": "2026-12-31"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created key and its secret.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "token": {
                      "$ref": "#/components/schemas/ApiKey"
                    },
                    "plain_token": {
                      "type": "string",
                      "description": "The key to send as `Authorization: Bearer <key>`. Shown once."
                    }
                  }
                },
                "example": {
                  "token": {
                    "id": "4f1d8c2b7e9a03c6d5b8e1f2a3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0",
                    "name": "Zapier",
                    "last_used_at": null,
                    "expires_at": "2026-12-31T23:59:59+00:00",
                    "created_at": "2026-10-08T12:00:00+00:00"
                  },
                  "plain_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI5Y..."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/api-keys/{apiToken}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiKeyId"
        }
      ],
      "delete": {
        "tags": [
          "API keys"
        ],
        "summary": "Delete API key",
        "operationId": "deleteApiKey",
        "description": "Revokes one of your API keys in this workspace. Integrations using it stop working at once. A key of another member or workspace returns `404`. You can revoke the key you are calling with.",
        "responses": {
          "204": {
            "description": "Revoked."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhooks",
        "operationId": "listWebhooks",
        "description": "Lists the workspace's webhooks, newest first. The signing secret is not included: read it with `GET /webhooks/{webhook}`. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of webhooks.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
                      "endpoint": "https://example.com/hooks/trypost",
                      "events": [
                        "post.published",
                        "post.failed"
                      ],
                      "status": "enabled",
                      "last_sent_at": "2026-10-08T14:00:03+00:00",
                      "paused_at": null,
                      "consecutive_failures": 0,
                      "created_at": "2026-09-15T10:00:00+00:00",
                      "updated_at": "2026-10-08T14:00:03+00:00"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/webhooks?page=1",
                    "last": "https://app.trypost.it/api/webhooks?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/webhooks?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/webhooks",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Create webhook",
        "operationId": "createWebhook",
        "description": "Creates an enabled webhook that sends the chosen post events to your endpoint. The response includes the `signing_secret`. The endpoint must be a public `http` or `https` URL: other schemes and private or local addresses are refused with `422` `This endpoint is not allowed.` on `endpoint`.\n\nEach delivery is a JSON `POST` with the body `{id, type, data, created_at}` and the header `X-Webhook-Signature`: the hex HMAC-SHA256 of the raw body, keyed with the webhook's `signing_secret`. Compare it with your own HMAC of the body before trusting it. A delivery that does not get a 2xx answer within 10 seconds is retried twice, a minute apart. Redirects are not followed.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "endpoint",
                  "events"
                ],
                "properties": {
                  "endpoint": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 255
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/WebhookEventType"
                    }
                  }
                }
              },
              "example": {
                "endpoint": "https://example.com/hooks/trypost",
                "events": [
                  "post.published",
                  "post.failed"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created webhook, with its signing secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "id": "9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
                  "endpoint": "https://example.com/hooks/trypost",
                  "events": [
                    "post.published",
                    "post.failed"
                  ],
                  "status": "enabled",
                  "last_sent_at": null,
                  "paused_at": null,
                  "consecutive_failures": 0,
                  "created_at": "2026-09-15T10:00:00+00:00",
                  "updated_at": "2026-10-08T14:00:03+00:00",
                  "signing_secret": "whsec_4qXbV8kP2mT7nR1sW9yZ3cE6hJ0aL5dF"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{webhook}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/WebhookId"
        }
      ],
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Get webhook",
        "operationId": "getWebhook",
        "description": "Returns one webhook, with its `signing_secret`.",
        "responses": {
          "200": {
            "description": "The webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "id": "9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
                  "endpoint": "https://example.com/hooks/trypost",
                  "events": [
                    "post.published",
                    "post.failed"
                  ],
                  "status": "enabled",
                  "last_sent_at": "2026-10-08T14:00:03+00:00",
                  "paused_at": null,
                  "consecutive_failures": 0,
                  "created_at": "2026-09-15T10:00:00+00:00",
                  "updated_at": "2026-10-08T14:00:03+00:00",
                  "signing_secret": "whsec_4qXbV8kP2mT7nR1sW9yZ3cE6hJ0aL5dF"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "put": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Update webhook",
        "operationId": "updateWebhook",
        "description": "Changes only the fields you send. `status` takes `enabled` or `disabled` (`paused` is set only by TryPost). Enabling a disabled or paused webhook resets `consecutive_failures` and `paused_at`. A new endpoint that is not a public `http` or `https` URL returns `422` on `endpoint`. The signing secret is not included in the response.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "endpoint": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 255
                  },
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/WebhookEventType"
                    }
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "enabled",
                      "disabled"
                    ]
                  }
                }
              },
              "example": {
                "events": [
                  "post.created",
                  "post.scheduled",
                  "post.unscheduled",
                  "post.published",
                  "post.partially_published",
                  "post.failed",
                  "post.deleted"
                ],
                "status": "enabled"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "id": "9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
                  "endpoint": "https://example.com/hooks/trypost",
                  "events": [
                    "post.created",
                    "post.scheduled",
                    "post.unscheduled",
                    "post.published",
                    "post.partially_published",
                    "post.failed",
                    "post.deleted"
                  ],
                  "status": "enabled",
                  "last_sent_at": "2026-10-08T14:00:03+00:00",
                  "paused_at": null,
                  "consecutive_failures": 0,
                  "created_at": "2026-09-15T10:00:00+00:00",
                  "updated_at": "2026-10-08T15:00:00+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete webhook",
        "operationId": "deleteWebhook",
        "description": "Deletes a webhook and its delivery logs. Deliveries already queued are dropped.",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{webhook}/logs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/WebhookId"
        }
      ],
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook logs",
        "operationId": "listWebhookLogs",
        "description": "Lists the webhook's deliveries, newest first, with the body sent and the endpoint's answer. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of deliveries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookLog"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9b2c3d50-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
                      "event_type": "post.published",
                      "payload": {
                        "id": "9b2c3d50-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
                        "type": "post.published",
                        "data": {
                          "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
                          "workspace_id": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
                          "user_id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                          "status": "published",
                          "created_via": "api",
                          "content": "We just shipped scheduled threads. Here is how they work.",
                          "scheduled_at": "2026-10-08T14:00:00+00:00",
                          "published_at": "2026-10-08T14:00:02+00:00",
                          "created_at": "2026-10-08T13:20:11+00:00",
                          "updated_at": "2026-10-08T14:00:02+00:00",
                          "author": {
                            "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                            "name": "Ana Souza"
                          },
                          "workspace": {
                            "id": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
                            "name": "TryPost"
                          },
                          "labels": [
                            {
                              "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                              "name": "Launch",
                              "color": "#2563EB"
                            }
                          ],
                          "media": [],
                          "platforms": [
                            {
                              "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                              "social_account_id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                              "platform": "x",
                              "content_type": "x_post",
                              "enabled": true,
                              "status": "published",
                              "platform_post_id": "1843456789012345678",
                              "platform_url": "https://x.com/trypostit/status/1843456789012345678",
                              "published_at": "2026-10-08T14:00:02+00:00",
                              "error_message": null,
                              "error_context": null,
                              "display_name": "TryPost",
                              "display_username": "trypostit",
                              "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                              "meta": [],
                              "social_account": {
                                "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                                "platform": "x",
                                "display_name": "TryPost",
                                "username": "trypostit",
                                "status": "connected"
                              }
                            }
                          ]
                        },
                        "created_at": "2026-10-08T14:00:02+00:00"
                      },
                      "response_status": 200,
                      "response_body": "ok",
                      "delivered_at": "2026-10-08T14:00:03+00:00",
                      "failed_at": null,
                      "attempts": 1,
                      "created_at": "2026-10-08T14:00:02+00:00"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/webhooks/9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e/logs?page=1",
                    "last": "https://app.trypost.it/api/webhooks/9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e/logs?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/webhooks/9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e/logs?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/webhooks/9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e/logs",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{webhook}/logs/{webhookLog}/replay": {
      "parameters": [
        {
          "$ref": "#/components/parameters/WebhookId"
        },
        {
          "$ref": "#/components/parameters/WebhookLogId"
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Replay webhook log",
        "operationId": "replayWebhookLog",
        "description": "Sends the `data` of a past delivery again, in the background, even when the webhook is disabled or paused. The replay is a new delivery: it has its own log, a new body `id` and `created_at`, and is signed with the current secret. A log of another webhook returns `404`.",
        "responses": {
          "200": {
            "description": "The replay was queued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "replayed": {
                      "type": "boolean",
                      "const": true
                    }
                  }
                },
                "example": {
                  "replayed": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{webhook}/rotate-secret": {
      "parameters": [
        {
          "$ref": "#/components/parameters/WebhookId"
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Rotate webhook secret",
        "operationId": "rotateWebhookSecret",
        "description": "Replaces the webhook's signing secret. Deliveries from now on are signed with the new secret, which the response returns; the old one stops matching at once.",
        "responses": {
          "200": {
            "description": "The webhook with its new signing secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "id": "9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
                  "endpoint": "https://example.com/hooks/trypost",
                  "events": [
                    "post.published",
                    "post.failed"
                  ],
                  "status": "enabled",
                  "last_sent_at": "2026-10-08T14:00:03+00:00",
                  "paused_at": null,
                  "consecutive_failures": 0,
                  "created_at": "2026-09-15T10:00:00+00:00",
                  "updated_at": "2026-10-08T15:05:00+00:00",
                  "signing_secret": "whsec_9tYu2HnB7cXv4QmZ1kLp8RsD3fGw6EjA"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/webhooks/{webhook}/send-test": {
      "parameters": [
        {
          "$ref": "#/components/parameters/WebhookId"
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Send webhook test",
        "operationId": "sendWebhookTest",
        "description": "Sends a signed test event to the endpoint now and waits up to 5 seconds for the answer: `{id, type: \"webhook.test\", data: {}, created_at}`. It is not logged and does not change the failure count. When the endpoint is not allowed, unreachable or answers with a non-2xx status, the request returns `422` with the reason on `endpoint` (for example `The endpoint returned HTTP 500.`).",
        "responses": {
          "200": {
            "description": "The endpoint answered with a 2xx status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tested": {
                      "type": "boolean",
                      "const": true
                    }
                  }
                },
                "example": {
                  "tested": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/repurpose-source-formats": {
      "get": {
        "tags": [
          "Repurposes"
        ],
        "summary": "List repurpose source formats",
        "operationId": "listRepurposeSourceFormats",
        "description": "Lists the values for `source_format`. Not paginated.",
        "responses": {
          "200": {
            "description": "The source formats.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "value": {
                            "type": "string",
                            "enum": [
                              "reel",
                              "video",
                              "story"
                            ]
                          },
                          "label": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "value": "reel",
                      "label": "Reels"
                    },
                    {
                      "value": "video",
                      "label": "Videos"
                    },
                    {
                      "value": "story",
                      "label": "Stories"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/repurposes": {
      "get": {
        "tags": [
          "Repurposes"
        ],
        "summary": "List repurposes",
        "operationId": "listRepurposes",
        "description": "Lists the workspace's repurposes, newest first, with the source account and the count of videos repurposed. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of repurposes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Repurpose"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                      "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                      "source_format": "reel",
                      "publish_mode": "publish",
                      "destinations": [
                        {
                          "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                          "content_type": "tiktok_video",
                          "meta": {
                            "privacy_level": "PUBLIC_TO_EVERYONE"
                          }
                        },
                        {
                          "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                          "content_type": "youtube_short"
                        }
                      ],
                      "status": "active",
                      "paused_reason": null,
                      "activated_at": "2026-10-01T09:00:00+00:00",
                      "last_polled_at": "2026-10-08T13:45:00+00:00",
                      "next_poll_at": "2026-10-08T14:00:00+00:00",
                      "last_error": null,
                      "created_at": "2026-09-30T18:00:00+00:00",
                      "updated_at": "2026-10-08T13:45:00+00:00",
                      "source_account": {
                        "id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                        "platform": "instagram",
                        "display_name": "TryPost",
                        "username": "trypost.it",
                        "status": "connected",
                        "has_posting_schedule": false,
                        "timezone": "America/Sao_Paulo",
                        "posting_goal": null,
                        "max_content_length": 2200,
                        "long_posts": false,
                        "verified_badge": null
                      },
                      "published_items_count": 12
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/repurposes?page=1",
                    "last": "https://app.trypost.it/api/repurposes?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/repurposes?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/repurposes",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "tags": [
          "Repurposes"
        ],
        "summary": "Create repurpose",
        "operationId": "createRepurpose",
        "description": "Creates a repurpose as a draft: it does nothing until you activate it. A source account that already feeds a repurpose of the same format returns `422` on `source_social_account_id`; a destination that is the source returns `422` on that destination's `social_account_id`. Each new video's caption is fitted to every destination: hashtags past the network's cap are dropped, and a caption longer than the account's limit is shortened (with AI when available, otherwise cut at a word).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "source_social_account_id"
                ],
                "properties": {
                  "source_social_account_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Instagram (direct or through Facebook) or Facebook account of this workspace to watch. One repurpose per source account and format."
                  },
                  "source_format": {
                    "type": "string",
                    "enum": [
                      "reel",
                      "video",
                      "story"
                    ],
                    "default": "reel",
                    "description": "Which videos of the source to repurpose. See `GET /repurpose-source-formats`."
                  },
                  "publish_mode": {
                    "type": "string",
                    "enum": [
                      "publish",
                      "draft"
                    ],
                    "default": "publish"
                  },
                  "destinations": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/RepurposeDestination"
                    },
                    "description": "Where each new video goes. Replaces the whole list."
                  }
                }
              },
              "example": {
                "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                "source_format": "reel",
                "publish_mode": "publish",
                "destinations": [
                  {
                    "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                    "content_type": "tiktok_video",
                    "meta": {
                      "privacy_level": "PUBLIC_TO_EVERYONE"
                    }
                  },
                  {
                    "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                    "content_type": "youtube_short"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created repurpose.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Repurpose"
                },
                "example": {
                  "id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                  "source_format": "reel",
                  "publish_mode": "publish",
                  "destinations": [
                    {
                      "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                      "content_type": "tiktok_video",
                      "meta": {
                        "privacy_level": "PUBLIC_TO_EVERYONE"
                      }
                    },
                    {
                      "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                      "content_type": "youtube_short"
                    }
                  ],
                  "status": "draft",
                  "paused_reason": null,
                  "activated_at": null,
                  "last_polled_at": null,
                  "next_poll_at": null,
                  "last_error": null,
                  "created_at": "2026-09-30T18:00:00+00:00",
                  "updated_at": "2026-09-30T18:00:00+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/repurposes/{repurpose}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RepurposeId"
        }
      ],
      "get": {
        "tags": [
          "Repurposes"
        ],
        "summary": "Get repurpose",
        "operationId": "getRepurpose",
        "description": "Returns one repurpose.",
        "responses": {
          "200": {
            "description": "The repurpose.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Repurpose"
                },
                "example": {
                  "id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                  "source_format": "reel",
                  "publish_mode": "publish",
                  "destinations": [
                    {
                      "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                      "content_type": "tiktok_video",
                      "meta": {
                        "privacy_level": "PUBLIC_TO_EVERYONE"
                      }
                    },
                    {
                      "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                      "content_type": "youtube_short"
                    }
                  ],
                  "status": "active",
                  "paused_reason": null,
                  "activated_at": "2026-10-01T09:00:00+00:00",
                  "last_polled_at": "2026-10-08T13:45:00+00:00",
                  "next_poll_at": "2026-10-08T14:00:00+00:00",
                  "last_error": null,
                  "created_at": "2026-09-30T18:00:00+00:00",
                  "updated_at": "2026-10-08T13:45:00+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "put": {
        "tags": [
          "Repurposes"
        ],
        "summary": "Update repurpose",
        "operationId": "updateRepurpose",
        "description": "Changes only the fields you send. On a repurpose that has been activated, changing the source account or format restarts it from now: only videos posted after the change are repurposed. An active repurpose must keep a connected source and at least one destination of the workspace, and its destinations need the settings their network requires to publish.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "source_social_account_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Instagram (direct or through Facebook) or Facebook account of this workspace to watch. One repurpose per source account and format."
                  },
                  "source_format": {
                    "type": "string",
                    "enum": [
                      "reel",
                      "video",
                      "story"
                    ],
                    "description": "Which videos of the source to repurpose. See `GET /repurpose-source-formats`."
                  },
                  "publish_mode": {
                    "type": "string",
                    "enum": [
                      "publish",
                      "draft"
                    ]
                  },
                  "destinations": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/RepurposeDestination"
                    },
                    "description": "Where each new video goes. Replaces the whole list."
                  }
                }
              },
              "example": {
                "publish_mode": "draft"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated repurpose.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Repurpose"
                },
                "example": {
                  "id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                  "source_format": "reel",
                  "publish_mode": "draft",
                  "destinations": [
                    {
                      "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                      "content_type": "tiktok_video",
                      "meta": {
                        "privacy_level": "PUBLIC_TO_EVERYONE"
                      }
                    },
                    {
                      "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                      "content_type": "youtube_short"
                    }
                  ],
                  "status": "active",
                  "paused_reason": null,
                  "activated_at": "2026-10-01T09:00:00+00:00",
                  "last_polled_at": "2026-10-08T13:45:00+00:00",
                  "next_poll_at": "2026-10-08T14:00:00+00:00",
                  "last_error": null,
                  "created_at": "2026-09-30T18:00:00+00:00",
                  "updated_at": "2026-10-08T15:10:00+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "delete": {
        "tags": [
          "Repurposes"
        ],
        "summary": "Delete repurpose",
        "operationId": "deleteRepurpose",
        "description": "Deletes a repurpose and its item history. Posts it already created stay.",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/repurposes/{repurpose}/activate": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RepurposeId"
        }
      ],
      "post": {
        "tags": [
          "Repurposes"
        ],
        "summary": "Activate repurpose",
        "operationId": "activateRepurpose",
        "description": "Starts a draft or disabled repurpose. Only videos posted from now on are repurposed. It needs a connected source account (`422` on `source_social_account_id`) and at least one destination that is still in the workspace (`422` on `destinations`); destinations whose account was removed are skipped. Each usable destination needs the settings its network requires to publish (`422` on `destinations`). From any other status the request returns `422` on `status`.",
        "responses": {
          "200": {
            "description": "The active repurpose.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Repurpose"
                },
                "example": {
                  "id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                  "source_format": "reel",
                  "publish_mode": "publish",
                  "destinations": [
                    {
                      "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                      "content_type": "tiktok_video",
                      "meta": {
                        "privacy_level": "PUBLIC_TO_EVERYONE"
                      }
                    },
                    {
                      "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                      "content_type": "youtube_short"
                    }
                  ],
                  "status": "active",
                  "paused_reason": null,
                  "activated_at": "2026-10-08T15:15:00+00:00",
                  "last_polled_at": null,
                  "next_poll_at": null,
                  "last_error": null,
                  "created_at": "2026-09-30T18:00:00+00:00",
                  "updated_at": "2026-10-08T15:15:00+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/repurposes/{repurpose}/pause": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RepurposeId"
        }
      ],
      "post": {
        "tags": [
          "Repurposes"
        ],
        "summary": "Pause repurpose",
        "operationId": "pauseRepurpose",
        "description": "Pauses an active repurpose. When you resume it, videos posted while it was paused are repurposed too. From any other status the request returns `422` on `status`.",
        "responses": {
          "200": {
            "description": "The paused repurpose.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Repurpose"
                },
                "example": {
                  "id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                  "source_format": "reel",
                  "publish_mode": "publish",
                  "destinations": [
                    {
                      "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                      "content_type": "tiktok_video",
                      "meta": {
                        "privacy_level": "PUBLIC_TO_EVERYONE"
                      }
                    },
                    {
                      "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                      "content_type": "youtube_short"
                    }
                  ],
                  "status": "paused",
                  "paused_reason": null,
                  "activated_at": "2026-10-01T09:00:00+00:00",
                  "last_polled_at": "2026-10-08T13:45:00+00:00",
                  "next_poll_at": "2026-10-08T14:00:00+00:00",
                  "last_error": null,
                  "created_at": "2026-09-30T18:00:00+00:00",
                  "updated_at": "2026-10-08T14:30:00+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/repurposes/{repurpose}/resume": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RepurposeId"
        }
      ],
      "post": {
        "tags": [
          "Repurposes"
        ],
        "summary": "Resume repurpose",
        "operationId": "resumeRepurpose",
        "description": "Resumes a paused repurpose, with the same checks as activation. After a pause you made, it picks up where it stopped, including videos posted while paused. After a pause TryPost made (`paused_reason` set, for example the source account was disconnected), it starts from now. From any other status the request returns `422` on `status`.",
        "responses": {
          "200": {
            "description": "The active repurpose.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Repurpose"
                },
                "example": {
                  "id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                  "source_format": "reel",
                  "publish_mode": "publish",
                  "destinations": [
                    {
                      "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                      "content_type": "tiktok_video",
                      "meta": {
                        "privacy_level": "PUBLIC_TO_EVERYONE"
                      }
                    },
                    {
                      "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                      "content_type": "youtube_short"
                    }
                  ],
                  "status": "active",
                  "paused_reason": null,
                  "activated_at": "2026-10-01T09:00:00+00:00",
                  "last_polled_at": "2026-10-08T13:45:00+00:00",
                  "next_poll_at": "2026-10-08T14:00:00+00:00",
                  "last_error": null,
                  "created_at": "2026-09-30T18:00:00+00:00",
                  "updated_at": "2026-10-08T14:45:00+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/repurposes/{repurpose}/disable": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RepurposeId"
        }
      ],
      "post": {
        "tags": [
          "Repurposes"
        ],
        "summary": "Disable repurpose",
        "operationId": "disableRepurpose",
        "description": "Turns off an active or paused repurpose. Activating it again starts from that moment, so videos posted while it was off are not repurposed. From any other status the request returns `422` on `status`.",
        "responses": {
          "200": {
            "description": "The disabled repurpose.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Repurpose"
                },
                "example": {
                  "id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "source_social_account_id": "9c8b7a69-4c5d-4e6f-8a0b-2c3d4e5f6071",
                  "source_format": "reel",
                  "publish_mode": "publish",
                  "destinations": [
                    {
                      "social_account_id": "9c8b7a67-2a3b-4c5d-8e9f-0a1b2c3d4e5f",
                      "content_type": "tiktok_video",
                      "meta": {
                        "privacy_level": "PUBLIC_TO_EVERYONE"
                      }
                    },
                    {
                      "social_account_id": "9c8b7a6a-5d6e-4f70-9b1c-3d4e5f607182",
                      "content_type": "youtube_short"
                    }
                  ],
                  "status": "disabled",
                  "paused_reason": null,
                  "activated_at": null,
                  "last_polled_at": "2026-10-08T13:45:00+00:00",
                  "next_poll_at": null,
                  "last_error": null,
                  "created_at": "2026-09-30T18:00:00+00:00",
                  "updated_at": "2026-10-08T15:00:00+00:00"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/repurposes/{repurpose}/items": {
      "parameters": [
        {
          "$ref": "#/components/parameters/RepurposeId"
        }
      ],
      "get": {
        "tags": [
          "Repurposes"
        ],
        "summary": "List repurpose items",
        "operationId": "listRepurposeItems",
        "description": "Lists the source videos the repurpose has picked up, newest first (by when they were posted on the source), with the posts created for each. Page size is set by the server: read `meta.per_page`.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of items.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RepurposeItem"
                      }
                    },
                    "links": {
                      "$ref": "#/components/schemas/PaginationLinks"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/PaginationMeta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "9a1b2c40-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
                      "repurpose_id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                      "source_media_id": "18045678901234567",
                      "source_permalink": "https://www.instagram.com/reel/DAbCdEfGhIj/",
                      "source_created_at": "2026-10-07T21:10:00+00:00",
                      "status": "published",
                      "reason": null,
                      "error": null,
                      "posts": [
                        {
                          "id": "9d3c1f40-7c8d-4e9f-8a0b-1c2d3e4f5a6b",
                          "platforms": [
                            {
                              "platform": "tiktok",
                              "status": "published"
                            }
                          ]
                        }
                      ],
                      "created_at": "2026-10-07T21:15:00+00:00",
                      "updated_at": "2026-10-07T21:16:30+00:00"
                    }
                  ],
                  "links": {
                    "first": "https://app.trypost.it/api/repurposes/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/items?page=1",
                    "last": "https://app.trypost.it/api/repurposes/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/items?page=1",
                    "prev": null,
                    "next": null
                  },
                  "meta": {
                    "current_page": 1,
                    "from": 1,
                    "last_page": 1,
                    "links": [
                      {
                        "url": null,
                        "label": "&laquo; Previous",
                        "page": null,
                        "active": false
                      },
                      {
                        "url": "https://app.trypost.it/api/repurposes/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/items?page=1",
                        "label": "1",
                        "page": 1,
                        "active": true
                      },
                      {
                        "url": null,
                        "label": "Next &raquo;",
                        "page": null,
                        "active": false
                      }
                    ],
                    "path": "https://app.trypost.it/api/repurposes/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/items",
                    "per_page": 25,
                    "to": 1,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/content-types": {
      "get": {
        "tags": [
          "Platform"
        ],
        "summary": "List content types",
        "operationId": "listContentTypes",
        "description": "Lists every network with its text limit, hashtag limit, alt text limit, required settings (`required_meta`), default content type, and the media rules of each content type: media counts and sizes, formats, aspect ratios, whether text is sent (`captionless`) and whether thread replies are accepted. Use it to build `platforms[].content_type` and `meta` for posts. Not paginated.",
        "responses": {
          "200": {
            "description": "Every network.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "platforms": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PlatformContentTypes"
                      }
                    }
                  }
                },
                "example": {
                  "platforms": [
                    {
                      "platform": "x",
                      "label": "X",
                      "max_content_length": 280,
                      "max_hashtags": null,
                      "alt_text_max_length": 1000,
                      "required_meta": [],
                      "recommended_content_length": 220,
                      "allowed_media_types": [
                        "image",
                        "video"
                      ],
                      "default_content_type": "x_post",
                      "content_types": [
                        {
                          "value": "x_post",
                          "label": "Post",
                          "description": "Tweet with text and media",
                          "max_media_count": 4,
                          "min_media_count": 0,
                          "requires_media": false,
                          "accept_images": true,
                          "accept_videos": true,
                          "accept_documents": false,
                          "accepts_gif": true,
                          "accepts_mov": true,
                          "forbids_mixed_media": false,
                          "max_video_duration_sec": 1200,
                          "max_image_bytes": 5242880,
                          "max_video_bytes": 1073741824,
                          "max_document_bytes": null,
                          "aspect_ratio_min": null,
                          "aspect_ratio_max": null,
                          "video_aspect_ratio_min": null,
                          "video_aspect_ratio_max": null,
                          "auto_fits_image": false,
                          "supports_alt_text": true,
                          "supports_user_tags": false,
                          "supports_video_cover": false,
                          "image_min_width": null,
                          "image_min_height": null,
                          "image_max_width": null,
                          "image_max_height": null,
                          "captionless": false,
                          "document_must_be_alone": false,
                          "supports_thread_replies": true,
                          "max_thread_replies": 24
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Workspace API key from Settings → API Keys."
      }
    },
    "schemas": {
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "current_page": {
            "type": "integer"
          },
          "from": {
            "type": [
              "integer",
              "null"
            ]
          },
          "last_page": {
            "type": "integer"
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "label": {
                  "type": "string"
                },
                "page": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "active": {
                  "type": "boolean"
                }
              }
            }
          },
          "path": {
            "type": "string"
          },
          "per_page": {
            "type": "integer",
            "description": "Page size set by the server. Read it; do not assume a value."
          },
          "to": {
            "type": [
              "integer",
              "null"
            ]
          },
          "total": {
            "type": "integer"
          }
        }
      },
      "PaginationLinks": {
        "type": "object",
        "properties": {
          "first": {
            "type": [
              "string",
              "null"
            ]
          },
          "last": {
            "type": [
              "string",
              "null"
            ]
          },
          "prev": {
            "type": [
              "string",
              "null"
            ]
          },
          "next": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ErrorBody": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          }
        }
      },
      "ValidationErrorBody": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "RateLimitErrorBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "const": "rate_limit_exceeded"
          },
          "message": {
            "type": "string",
            "examples": [
              "Rate limit exceeded. Please retry after 30 seconds."
            ]
          }
        }
      },
      "ContentType": {
        "type": "string",
        "enum": [
          "instagram_feed",
          "instagram_reel",
          "instagram_story",
          "linkedin_post",
          "linkedin_page_post",
          "facebook_post",
          "facebook_reel",
          "facebook_story",
          "tiktok_video",
          "tiktok_photo",
          "youtube_short",
          "x_post",
          "threads_post",
          "threads_ghost_post",
          "pinterest_pin",
          "pinterest_video_pin",
          "pinterest_carousel",
          "bluesky_post",
          "mastodon_post",
          "telegram_post",
          "discord_message",
          "google_business_post"
        ],
        "description": "Post format on one network. It must belong to the destination's network. `GET /content-types` lists the formats of each network with their media rules. Instagram and Facebook stories publish no text."
      },
      "Platform": {
        "type": "string",
        "enum": [
          "linkedin",
          "linkedin-page",
          "x",
          "tiktok",
          "youtube",
          "facebook",
          "instagram",
          "instagram-facebook",
          "threads",
          "pinterest",
          "bluesky",
          "mastodon",
          "telegram",
          "discord",
          "google_business"
        ],
        "description": "Network of a social account. `linkedin-page` is a LinkedIn company page, `instagram-facebook` an Instagram account connected through a Facebook Page."
      },
      "Person": {
        "type": "object",
        "description": "A workspace member. Only the id and name are exposed.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "Label": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string",
            "description": "Hex color, `#RRGGBB`.",
            "examples": [
              "#2563EB"
            ]
          },
          "created_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-09-01 10:00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-09-01 10:00:00"
            ]
          }
        }
      },
      "SocialAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "platform": {
            "$ref": "#/components/schemas/Platform"
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "username": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "connected",
              "disconnected",
              "token_expired"
            ]
          },
          "has_posting_schedule": {
            "type": "boolean",
            "description": "Whether the channel has posting times. Queueing a post (`queue`) needs them."
          },
          "timezone": {
            "type": "string",
            "description": "IANA time zone of the channel. Queue slots and recurrence follow it."
          },
          "posting_goal": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Posts per week the channel aims for."
          },
          "max_content_length": {
            "type": "integer",
            "description": "Text limit of this account, in characters. An X account with long posts gets 25000."
          },
          "long_posts": {
            "type": "boolean",
            "description": "Whether this X account can publish long posts."
          },
          "verified_badge": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "blue",
              "business",
              "government",
              null
            ],
            "description": "X checkmark; `null` on other networks or unverified accounts. A badge alone does not mean long posts: read `long_posts`."
          }
        }
      },
      "MediaItemMeta": {
        "type": "object",
        "description": "Editable settings of one media item. Other keys the server measured (for example `width`, `height`, `duration`) may also appear in responses.",
        "properties": {
          "alt_text": {
            "type": "string",
            "maxLength": 2000,
            "description": "Accessibility description. Applies to images; each network truncates it to its own cap."
          },
          "user_tags": {
            "type": "array",
            "maxItems": 20,
            "description": "People tagged on an Instagram image.",
            "items": {
              "type": "object",
              "required": [
                "username",
                "x",
                "y"
              ],
              "properties": {
                "username": {
                  "type": "string",
                  "pattern": "^@?[A-Za-z0-9._]{1,30}$",
                  "description": "Public Instagram username. A leading `@` is dropped."
                },
                "x": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Offset from the left edge, 0 to 1."
                },
                "y": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Offset from the top edge, 0 to 1."
                }
              }
            }
          },
          "cover_offset_ms": {
            "type": "integer",
            "minimum": 0,
            "description": "Video frame used as the cover, in milliseconds from the start. Cannot pass the end of the video."
          }
        }
      },
      "MediaReference": {
        "type": "object",
        "description": "One media item to put on a post. Give **exactly one** of `upload_token`, `url` or `id`, otherwise the request fails with `Each media item needs exactly one of upload_token, url or id.`",
        "properties": {
          "upload_token": {
            "type": "string",
            "format": "uuid",
            "description": "Token from `POST /uploads` or a signed upload URL. Single use: the first post that takes it consumes it. Kept 24 hours."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "Public `http` or `https` URL of the file itself. Downloaded once per request; redirects are not followed and private hosts are refused."
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Id of a media item already in this workspace (for example `media[].id` of another post). The file is copied."
          },
          "alt": {
            "type": "string",
            "maxLength": 2000,
            "description": "Alt text shorthand. Applies to images only; `meta.alt_text` wins when both are sent."
          },
          "meta": {
            "$ref": "#/components/schemas/MediaItemMeta"
          }
        },
        "examples": [
          {
            "url": "https://example.com/launch.jpg",
            "alt": "Product launch banner"
          }
        ]
      },
      "MediaItem": {
        "type": "object",
        "description": "A media item as stored on a post.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Media id. Pass it as `media[].id` to reuse the file on another post."
          },
          "path": {
            "type": "string",
            "description": "Storage path, `medias/{uuid}.{ext}`."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Public URL of the file."
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "image",
              "video",
              "document",
              null
            ],
            "description": "`null` on older items stored without a type."
          },
          "mime_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "original_filename": {
            "type": [
              "string",
              "null"
            ]
          },
          "size": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Size in bytes."
          },
          "meta": {
            "$ref": "#/components/schemas/MediaItemMeta"
          },
          "source": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "ai",
              "unsplash",
              "google_drive",
              "google_photos",
              "canva",
              null
            ],
            "description": "Where the file came from in the app. Present only on items added from one of these sources."
          },
          "source_meta": {
            "type": [
              "object",
              "null"
            ],
            "description": "Details from that source. Present only when the source gave any."
          }
        },
        "examples": [
          {
            "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
            "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
            "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
            "type": "image",
            "mime_type": "image/jpeg",
            "original_filename": "launch.jpg",
            "size": 482113,
            "meta": {
              "width": 1080,
              "height": 1350,
              "alt_text": "Product launch banner"
            }
          }
        ]
      },
      "ThreadReply": {
        "type": "object",
        "description": "One reply published under the post as a thread (X, Bluesky and Mastodon). A reply needs text or media. Its text must fit the account limit (Bluesky 300, Mastodon 500 including the content warning, which every reply repeats, X 280 or 25000 for accounts with long posts). Its media belongs to this reply only and follows the media rules of a post on that network.",
        "properties": {
          "text": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 25000
          },
          "media": {
            "type": "array",
            "maxItems": 4,
            "description": "Up to 4 media items, each given by `url`, `id` or `upload_token`, with optional `meta.alt_text`.",
            "items": {
              "$ref": "#/components/schemas/MediaReference"
            }
          }
        },
        "examples": [
          {
            "text": "3/ Full changelog below.",
            "media": [
              {
                "url": "https://example.com/changelog.png"
              }
            ]
          }
        ]
      },
      "PlatformMetaX": {
        "type": "object",
        "title": "X",
        "description": "Settings for `x_post`.",
        "properties": {
          "thread_replies": {
            "type": [
              "array",
              "null"
            ],
            "maxItems": 24,
            "description": "Up to 24 replies published under the post as a thread. Each item is a `ThreadReply`, or a plain string for a text-only reply. On update this list replaces the stored one.",
            "items": {
              "oneOf": [
                {
                  "type": "string",
                  "maxLength": 25000,
                  "title": "Text-only reply"
                },
                {
                  "$ref": "#/components/schemas/ThreadReply"
                }
              ]
            }
          },
          "is_ai_generated": {
            "type": "boolean",
            "description": "Discloses AI-generated media on the post (sent to X as `made_with_ai`)."
          }
        }
      },
      "PlatformMetaBluesky": {
        "type": "object",
        "title": "Bluesky",
        "description": "Settings for `bluesky_post`.",
        "properties": {
          "thread_replies": {
            "type": [
              "array",
              "null"
            ],
            "maxItems": 24,
            "description": "Up to 24 replies published under the post as a thread. Each item is a `ThreadReply`, or a plain string for a text-only reply. On update this list replaces the stored one.",
            "items": {
              "oneOf": [
                {
                  "type": "string",
                  "maxLength": 25000,
                  "title": "Text-only reply"
                },
                {
                  "$ref": "#/components/schemas/ThreadReply"
                }
              ]
            }
          },
          "link_preview": {
            "type": "boolean",
            "default": true,
            "description": "Send `false` (a real boolean) to publish a text post with a link without its preview card."
          }
        }
      },
      "PlatformMetaMastodon": {
        "type": "object",
        "title": "Mastodon",
        "description": "Settings for `mastodon_post`.",
        "properties": {
          "thread_replies": {
            "type": [
              "array",
              "null"
            ],
            "maxItems": 24,
            "description": "Up to 24 replies published under the post as a thread. Each item is a `ThreadReply`, or a plain string for a text-only reply. On update this list replaces the stored one.",
            "items": {
              "oneOf": [
                {
                  "type": "string",
                  "maxLength": 25000,
                  "title": "Text-only reply"
                },
                {
                  "$ref": "#/components/schemas/ThreadReply"
                }
              ]
            }
          },
          "spoiler_text": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 500,
            "description": "Content warning. Counts toward the 500-character post limit."
          }
        }
      },
      "PlatformMetaTikTok": {
        "type": "object",
        "title": "TikTok",
        "description": "Settings for `tiktok_video` and `tiktok_photo`. `privacy_level` is required to schedule or publish; read the allowed values from `GET /social-accounts/{account}/tiktok-creator-info` and keep `allow_comments`, `allow_duet` and `allow_stitch` false when it reports them disabled. `SELF_ONLY` cannot be combined with `brand_content_toggle`.",
        "properties": {
          "privacy_level": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "PUBLIC_TO_EVERYONE",
              "MUTUAL_FOLLOW_FRIENDS",
              "FOLLOWER_OF_CREATOR",
              "SELF_ONLY",
              null
            ],
            "description": "Who can see the post. Required to schedule or publish."
          },
          "allow_comments": {
            "type": "boolean"
          },
          "allow_duet": {
            "type": "boolean",
            "description": "`tiktok_video` only."
          },
          "allow_stitch": {
            "type": "boolean",
            "description": "`tiktok_video` only."
          },
          "is_aigc": {
            "type": "boolean",
            "description": "AI-generated content label. `tiktok_video` only."
          },
          "auto_add_music": {
            "type": "boolean",
            "description": "`tiktok_photo` only."
          },
          "disclose": {
            "type": "boolean",
            "description": "Commercial content disclosure."
          },
          "brand_content_toggle": {
            "type": "boolean",
            "description": "Paid partnership."
          },
          "brand_organic_toggle": {
            "type": "boolean",
            "description": "Promotes your own brand."
          }
        }
      },
      "PlatformMetaPinterest": {
        "type": "object",
        "title": "Pinterest",
        "description": "Settings for `pinterest_pin`, `pinterest_video_pin` and `pinterest_carousel`. The pin description is the post content; a video pin cover is the media item's `meta.cover_offset_ms`.",
        "properties": {
          "board_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Board to pin to. Required to schedule or publish. List boards with `GET /social-accounts/{account}/boards` or create one with `POST /social-accounts/{account}/boards`."
          },
          "title": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100
          },
          "link": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "maxLength": 2048,
            "description": "Destination URL (`http` or `https`)."
          }
        }
      },
      "PlatformMetaDiscord": {
        "type": "object",
        "title": "Discord",
        "description": "Settings for `discord_message`.",
        "properties": {
          "channel_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Channel to post in. Required to schedule or publish. List channels with `GET /social-accounts/{account}/channels`."
          },
          "channel_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Channel name shown in the app."
          },
          "mentions": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object",
              "required": [
                "token"
              ],
              "properties": {
                "token": {
                  "type": "string",
                  "description": "Mention token, for example `@everyone` or `<@&roleId>`."
                },
                "label": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "embeds": {
            "type": [
              "array",
              "null"
            ],
            "maxItems": 10,
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "maxLength": 256
                },
                "description": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "maxLength": 4096
                },
                "url": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uri"
                },
                "image": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uri",
                  "description": "Image URL."
                },
                "color": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "pattern": "^#?[0-9A-Fa-f]{6}$",
                  "description": "Hex color, `#RRGGBB`."
                }
              }
            }
          }
        }
      },
      "PlatformMetaYouTube": {
        "type": "object",
        "title": "YouTube",
        "description": "Settings for `youtube_short`. A post needs `title` or text to be scheduled or published.",
        "properties": {
          "title": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100,
            "description": "No `<` or `>` (refused even on drafts). Omitted, it is the first non-empty line of the text with `<` and `>` removed, cut to 100 characters."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Plain text, at most 5000 bytes. Omit or send `null` to use the post content."
          },
          "category_id": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "1",
              "2",
              "10",
              "15",
              "17",
              "19",
              "20",
              "22",
              "23",
              "24",
              "25",
              "26",
              "27",
              "28",
              "29",
              null
            ],
            "default": "22",
            "description": "YouTube category: 1 Film & Animation, 2 Autos & Vehicles, 10 Music, 15 Pets & Animals, 17 Sports, 19 Travel & Events, 20 Gaming, 22 People & Blogs, 23 Comedy, 24 Entertainment, 25 News & Politics, 26 Howto & Style, 27 Education, 28 Science & Technology, 29 Nonprofits & Activism. An integer id is accepted and stored as a string."
          },
          "privacy_status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "public",
              "unlisted",
              "private",
              null
            ],
            "default": "public"
          },
          "license": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "youtube",
              "creativeCommon",
              null
            ],
            "default": "youtube"
          },
          "notify_subscribers": {
            "type": "boolean",
            "default": true
          },
          "embeddable": {
            "type": "boolean",
            "default": true
          },
          "made_for_kids": {
            "type": "boolean",
            "default": false
          },
          "is_ai_generated": {
            "type": "boolean",
            "description": "Discloses altered or synthetic content."
          }
        }
      },
      "PlatformMetaInstagram": {
        "type": "object",
        "title": "Instagram",
        "description": "Settings for `instagram_feed`, `instagram_reel` and `instagram_story` (both `instagram` and `instagram-facebook` accounts). An `instagram_feed` post with a single video publishes as a Reel. People tags are the media item's `meta.user_tags`; a video cover is `meta.cover_offset_ms`. A post may carry at most 5 hashtags.",
        "properties": {
          "is_ai_generated": {
            "type": "boolean",
            "description": "AI-generated label (feed, reels, stories, carousels)."
          },
          "share_to_feed": {
            "type": "boolean",
            "default": true,
            "description": "`instagram_reel` only: also show the Reel in the profile feed."
          }
        }
      },
      "PlatformMetaThreads": {
        "type": "object",
        "title": "Threads",
        "description": "Settings for `threads_post`. Use the content type `threads_ghost_post` for a text-only post archived after 24 hours (no media, no topic).",
        "properties": {
          "topic_tag": {
            "type": [
              "string",
              "null"
            ],
            "description": "Topic, 1 to 50 characters after a leading `#` is dropped, without `.` or `&`."
          }
        }
      },
      "PlatformMetaFacebook": {
        "type": "object",
        "title": "Facebook",
        "description": "Settings for `facebook_post`. Facebook reels and stories take no settings; stories publish no text.",
        "properties": {
          "link_preview": {
            "type": "boolean",
            "default": true,
            "description": "Send `false` (a real boolean) to publish a text post with a link without its preview card."
          }
        }
      },
      "PlatformMetaLinkedIn": {
        "type": "object",
        "title": "LinkedIn",
        "description": "Settings for `linkedin_post` and `linkedin_page_post`.",
        "properties": {
          "link_preview": {
            "type": "boolean",
            "default": true,
            "description": "Send `false` (a real boolean) to publish a text post with a link without its preview card."
          },
          "document_title": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 300,
            "description": "Title shown on a PDF document post. Defaults to the file name."
          }
        }
      },
      "PlatformMetaGoogleBusiness": {
        "type": "object",
        "title": "Google Business Profile",
        "description": "Settings for `google_business_post`. An `EVENT` or `OFFER` needs `event.title`, `event.start_date` and `event.end_date` (the title is the offer title), and cannot end before it starts.",
        "properties": {
          "topic_type": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "STANDARD",
              "EVENT",
              "OFFER",
              null
            ],
            "default": "STANDARD"
          },
          "call_to_action": {
            "type": [
              "object",
              "null"
            ],
            "description": "Button on the post. Not on `OFFER`.",
            "properties": {
              "action_type": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "NONE",
                  "BOOK",
                  "ORDER",
                  "SHOP",
                  "LEARN_MORE",
                  "SIGN_UP",
                  "CALL",
                  null
                ]
              },
              "url": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri",
                "maxLength": 2048,
                "description": "Required unless `action_type` is `NONE` or `CALL`."
              }
            }
          },
          "event": {
            "type": [
              "object",
              "null"
            ],
            "description": "Required on `EVENT` and `OFFER`.",
            "properties": {
              "title": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 58
              },
              "start_date": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date",
                "description": "`YYYY-MM-DD`."
              },
              "end_date": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date",
                "description": "`YYYY-MM-DD`, not before `start_date`."
              },
              "start_time": {
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^\\d{2}:\\d{2}$",
                "description": "`HH:MM`."
              },
              "end_time": {
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^\\d{2}:\\d{2}$",
                "description": "`HH:MM`."
              }
            }
          },
          "offer": {
            "type": [
              "object",
              "null"
            ],
            "description": "`OFFER` only.",
            "properties": {
              "coupon_code": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "redeem_online_url": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri",
                "maxLength": 2048
              },
              "terms_conditions": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 5000
              }
            }
          }
        }
      },
      "PlatformMetaNone": {
        "type": "object",
        "title": "Telegram",
        "description": "Telegram (and Facebook reels and stories) take no settings.",
        "properties": {}
      },
      "PlatformMeta": {
        "description": "Per-network settings of one destination. Pick the shape of the destination's network. Keys without a rule are dropped. Every known key is validated whatever the network, but only the keys of the destination's network are used when publishing. On update, `meta` is merged with the stored settings: send `null` for a key to clear it (string, list and object settings; boolean settings cannot be cleared, so send `true` or `false`); `thread_replies` replaces the whole list. Required to schedule or publish: TikTok `privacy_level`, Pinterest `board_id`, Discord `channel_id`, Google Business `event` on `EVENT`/`OFFER`, YouTube a title (`title` or the first line of the text). `GET /content-types` lists the unconditional ones (TikTok, Pinterest, Discord) per network as `required_meta`.",
        "anyOf": [
          {
            "$ref": "#/components/schemas/PlatformMetaX"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaBluesky"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaMastodon"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaTikTok"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaPinterest"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaDiscord"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaYouTube"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaInstagram"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaThreads"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaFacebook"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaLinkedIn"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaGoogleBusiness"
          },
          {
            "$ref": "#/components/schemas/PlatformMetaNone"
          }
        ]
      },
      "PostPlatform": {
        "type": "object",
        "description": "The post's destination: one social account and its format and settings.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Destination id. Use it as `platforms[].id` on `PUT /posts/{post}`."
          },
          "platform": {
            "$ref": "#/components/schemas/Platform"
          },
          "content_type": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ContentType"
              },
              {
                "type": "null"
              }
            ]
          },
          "meta": {
            "type": [
              "object",
              "array",
              "null"
            ],
            "maxItems": 0,
            "description": "Stored per-network settings (see `PlatformMeta`). Empty settings may serialize as an empty array."
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "pending",
              "publishing",
              "retrying",
              "pending_review",
              "published",
              "failed",
              "rejected",
              null
            ],
            "description": "Publishing state on this network. `retrying` waits for a retry after a network limit; `pending_review` and `rejected` come from networks that review posts (Google Business)."
          },
          "enabled": {
            "type": "boolean"
          },
          "platform_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Link to the published post on the network."
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "UTC, format `Y-m-d H:i:s`."
          },
          "error_message": {
            "type": [
              "string",
              "null"
            ]
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Account name, kept even after the account is disconnected."
          },
          "display_username": {
            "type": [
              "string",
              "null"
            ]
          },
          "display_avatar": {
            "type": [
              "string",
              "null"
            ]
          },
          "social_account": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SocialAccount"
              },
              {
                "type": "null"
              }
            ],
            "description": "The account, or `null` once it was removed (the `display_*` fields keep its name)."
          }
        }
      },
      "Post": {
        "type": "object",
        "description": "A post on one channel. Posts created together from several channels are independent posts that share a `post_group_id`.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "post_group_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Shared by the posts created in one batch."
          },
          "author": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ]
          },
          "content": {
            "type": [
              "string",
              "null"
            ],
            "description": "Post text, stored as sent (posts written in the app hold the editor's HTML)."
          },
          "media": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/MediaItem"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "pending_approval",
              "scheduled",
              "publishing",
              "published",
              "partially_published",
              "failed"
            ],
            "description": "`pending_approval` is a post a member who needs approval asked to schedule or publish."
          },
          "schedule_mode": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "queue",
              "custom",
              null
            ],
            "description": "`queue`: the post holds a slot of the channel's posting schedule. `custom`: it is scheduled at its own time."
          },
          "scheduled_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "UTC, format `Y-m-d H:i:s`."
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "UTC, format `Y-m-d H:i:s`."
          },
          "approval_requested_by": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who asked for approval (not always the author)."
          },
          "approval_requested_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "UTC, format `Y-m-d H:i:s`."
          },
          "approved_by": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ]
          },
          "approved_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "UTC, format `Y-m-d H:i:s`."
          },
          "recurrence": {
            "type": [
              "object",
              "null"
            ],
            "description": "Repeat rule, or `null`.",
            "properties": {
              "interval": {
                "type": "integer"
              },
              "frequency": {
                "type": "string",
                "enum": [
                  "day",
                  "week",
                  "month",
                  "year"
                ]
              },
              "remaining": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Repeats left after the next one."
              }
            }
          },
          "origin": {
            "type": "string",
            "enum": [
              "trypost",
              "network"
            ],
            "description": "`network` for posts imported from the network (published outside TryPost)."
          },
          "platforms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostPlatform"
            }
          },
          "labels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Label"
            }
          },
          "created_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`."
          },
          "updated_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`."
          }
        },
        "examples": [
          {
            "id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
            "post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
            "author": {
              "id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
              "name": "Ana Souza"
            },
            "content": "We just shipped scheduled threads. Here is how they work.",
            "media": [
              {
                "id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
                "path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                "url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
                "type": "image",
                "mime_type": "image/jpeg",
                "original_filename": "launch.jpg",
                "size": 482113,
                "meta": {
                  "width": 1080,
                  "height": 1350,
                  "alt_text": "Product launch banner"
                }
              }
            ],
            "status": "scheduled",
            "schedule_mode": "custom",
            "scheduled_at": "2026-10-12 14:00:00",
            "published_at": null,
            "approval_requested_by": null,
            "approval_requested_at": null,
            "approved_by": null,
            "approved_at": null,
            "recurrence": null,
            "origin": "trypost",
            "platforms": [
              {
                "id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
                "platform": "x",
                "content_type": "x_post",
                "meta": {
                  "thread_replies": [
                    {
                      "text": "2/ Replies publish under the first post.",
                      "media": []
                    }
                  ]
                },
                "status": "pending",
                "enabled": true,
                "platform_url": null,
                "published_at": null,
                "error_message": null,
                "display_name": "TryPost",
                "display_username": "trypostit",
                "display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
                "social_account": {
                  "id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
                  "platform": "x",
                  "display_name": "TryPost",
                  "username": "trypostit",
                  "status": "connected",
                  "has_posting_schedule": true,
                  "timezone": "America/Sao_Paulo",
                  "posting_goal": 5,
                  "max_content_length": 280,
                  "long_posts": false,
                  "verified_badge": null
                }
              }
            ],
            "labels": [
              {
                "id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
                "name": "Launch",
                "color": "#2563EB",
                "created_at": "2026-09-01 10:00:00",
                "updated_at": "2026-09-01 10:00:00"
              }
            ],
            "created_at": "2026-10-08 13:20:11",
            "updated_at": "2026-10-08 13:20:11"
          }
        ]
      },
      "PostNote": {
        "type": "object",
        "description": "An internal note on a post. Notes are never published.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "post_id": {
            "type": "string",
            "format": "uuid"
          },
          "body": {
            "type": "string"
          },
          "author": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "photo_url": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "created_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`."
          },
          "updated_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`."
          }
        }
      },
      "PublicationAnalytics": {
        "type": "object",
        "description": "Saved analytics of one publication: the latest daily snapshot collected from the network.",
        "properties": {
          "available": {
            "type": "boolean",
            "description": "Always `true` on `GET /analytics/publications/{publication}`."
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Always `null` on `GET /analytics/publications/{publication}`."
          },
          "publication": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "post_platform_id": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              },
              "social_account_key": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "platform": {
                "$ref": "#/components/schemas/Platform"
              },
              "origin": {
                "type": "string"
              },
              "content_type": {
                "type": "string"
              },
              "availability": {
                "type": "string",
                "enum": [
                  "available",
                  "deleted",
                  "unavailable"
                ],
                "description": "Always `available` on `GET /analytics/publications/{publication}`."
              },
              "provider_published_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "permalink": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "excerpt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "preview_metadata": {
                "type": [
                  "object",
                  "null"
                ]
              },
              "account_display_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "account_username": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "account_avatar_url": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "snapshot": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "date": {
                "type": "string",
                "format": "date"
              },
              "collected_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "provider_observed_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "reactions_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "comments_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "shares_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "saves_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "views_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "impressions_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "reach_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "engagement_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "exposure_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "exposure_kind": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "watch_time_milliseconds": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "average_watch_time_milliseconds": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "metrics": {
            "type": [
              "object",
              "array"
            ],
            "description": "Metrics the network reports for this publication, keyed by metric. An empty array `[]` when no snapshot has been collected yet. Keys (`reactions`, `comments`, `views`, `impressions`, `reach`, `engagement_rate`, ...). Each value is an object.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "value": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "unit": {
                  "type": "string"
                },
                "time_basis": {
                  "type": "string"
                },
                "precision": {
                  "type": "string"
                },
                "availability": {
                  "type": "string"
                },
                "provider_metric": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "period_start": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "period_end": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              }
            },
            "maxItems": 0
          }
        }
      },
      "PostMetrics": {
        "type": "object",
        "properties": {
          "post_id": {
            "type": "string",
            "format": "uuid"
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "post_platform_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "platform": {
                  "$ref": "#/components/schemas/Platform"
                },
                "status": {
                  "type": "string"
                },
                "platform_post_id": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "platform_url": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "metrics": {
                  "description": "The saved analytics, or `{unsupported: true, reason}` when there are none: `not_published`, `platform_not_supported` (LinkedIn, LinkedIn Page, Telegram, Discord and Google Business are not in analytics) or `not_collected` (not collected yet).",
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PublicationAnalytics"
                    },
                    {
                      "type": "object",
                      "title": "Unavailable",
                      "properties": {
                        "unsupported": {
                          "type": "boolean",
                          "const": true
                        },
                        "reason": {
                          "type": "string",
                          "enum": [
                            "not_published",
                            "platform_not_supported",
                            "not_collected"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "PostPreview": {
        "type": "object",
        "properties": {
          "post_id": {
            "type": "string",
            "format": "uuid"
          },
          "original_content": {
            "type": "string"
          },
          "original_length": {
            "type": "integer",
            "description": "Characters (code points) of the stored content."
          },
          "platforms": {
            "type": "array",
            "description": "One entry per enabled destination.",
            "items": {
              "type": "object",
              "properties": {
                "post_platform_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "platform": {
                  "$ref": "#/components/schemas/Platform"
                },
                "content_type": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "sanitized_content": {
                  "type": "string",
                  "description": "The text the publisher sends to the network."
                },
                "sanitized_length": {
                  "type": "integer"
                },
                "max_content_length": {
                  "type": "integer",
                  "description": "Text limit of the account (an X account with long posts gets 25000)."
                },
                "truncated": {
                  "type": "boolean",
                  "description": "Whether the sent text is shorter than the stored text."
                },
                "title": {
                  "type": "string",
                  "description": "YouTube only: the video title."
                },
                "description": {
                  "type": "string",
                  "description": "YouTube only: the video description."
                },
                "description_length_bytes": {
                  "type": "integer",
                  "description": "YouTube only. The limit is 5000 bytes."
                },
                "thread_replies": {
                  "type": "array",
                  "description": "X, Bluesky and Mastodon, when the post has replies.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string"
                      },
                      "media": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/MediaItem"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Upload": {
        "type": "object",
        "description": "A temporary upload. Pass `upload_token` as a media item before `expires_at`.",
        "properties": {
          "upload_token": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "document"
            ]
          },
          "mime_type": {
            "type": "string"
          },
          "size": {
            "type": "integer",
            "description": "Bytes."
          },
          "original_filename": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601. 24 hours after the upload; unused uploads are then deleted."
          }
        }
      },
      "SignedUpload": {
        "type": "object",
        "properties": {
          "upload_token": {
            "type": "string",
            "format": "uuid"
          },
          "media_id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "document"
            ]
          },
          "mime_type": {
            "type": "string"
          },
          "original_filename": {
            "type": "string"
          }
        }
      },
      "PinterestBoard": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Pinterest board id. Send it as `meta.board_id` on a Pinterest destination."
          },
          "name": {
            "type": "string"
          },
          "cover_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cover image of the board, when Pinterest has one."
          }
        }
      },
      "DiscordChannel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Discord channel id. Send it as `meta.channel_id` on a Discord destination."
          },
          "name": {
            "type": "string"
          }
        }
      },
      "TikTokCreatorInfo": {
        "type": "object",
        "description": "What TikTok allows this creator to publish right now.",
        "properties": {
          "can_post": {
            "type": "boolean",
            "description": "`false` when TikTok answered that the creator cannot post now (no privacy options)."
          },
          "privacy_level_options": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "PUBLIC_TO_EVERYONE",
                "MUTUAL_FOLLOW_FRIENDS",
                "FOLLOWER_OF_CREATOR",
                "SELF_ONLY"
              ]
            },
            "description": "Values allowed for `meta.privacy_level` on this account."
          },
          "comment_disabled": {
            "type": "boolean",
            "description": "Comments are off in the creator's TikTok settings: `allow_comments` has no effect."
          },
          "duet_disabled": {
            "type": "boolean"
          },
          "stitch_disabled": {
            "type": "boolean"
          },
          "max_video_post_duration_sec": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Longest video this creator may post, in seconds."
          },
          "creator_nickname": {
            "type": [
              "string",
              "null"
            ]
          },
          "creator_username": {
            "type": [
              "string",
              "null"
            ]
          },
          "creator_avatar_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "PostingDay": {
        "type": "object",
        "required": [
          "day",
          "enabled",
          "times"
        ],
        "properties": {
          "day": {
            "type": "integer",
            "minimum": 0,
            "maximum": 6,
            "description": "Day of the week: `0` is Sunday, `6` is Saturday. Send a JSON integer, not a string."
          },
          "enabled": {
            "type": "boolean",
            "description": "A disabled day keeps its times but offers no queue slots."
          },
          "times": {
            "type": "array",
            "maxItems": 4,
            "items": {
              "type": "string",
              "pattern": "^\\d{2}:\\d{2}$",
              "examples": [
                "09:00"
              ]
            },
            "description": "Posting times, `H:i` in the channel's time zone, at most 4 per day, no duplicates. Stored sorted."
          }
        }
      },
      "ChannelPostingSchedule": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Social account id."
          },
          "timezone": {
            "type": "string",
            "description": "IANA time zone of the channel. Posting times and queue slots are in this zone."
          },
          "posting_goal": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 28,
            "description": "Posts per week the channel aims for."
          },
          "posting_schedule": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/PostingDay"
            },
            "description": "Seven days, Sunday first. `null` when the channel has no posting times (posts cannot use `queue`)."
          }
        }
      },
      "Idea": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "idea_stage_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Stage (board column) of the idea. `null` is Unassigned."
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "body": {
            "type": [
              "string",
              "null"
            ]
          },
          "position": {
            "type": "integer",
            "description": "Order within its stage, starting at 0."
          },
          "media": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MediaItem"
            }
          },
          "labels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Label"
            }
          },
          "created_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-10-07 18:20:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-10-07 18:20:00"
            ]
          }
        }
      },
      "IdeaStage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "position": {
            "type": "integer",
            "description": "Board order, starting at 0."
          },
          "ideas_count": {
            "type": "integer",
            "description": "Ideas in the stage. Only in `GET /idea-stages` and `PUT /idea-stages/order`."
          },
          "created_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-09-20 12:00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-09-20 12:00:00"
            ]
          }
        }
      },
      "MetricComparison": {
        "type": "object",
        "description": "A metric for the range and for the previous range of the same length.",
        "properties": {
          "value": {
            "type": [
              "number",
              "null"
            ],
            "description": "Value for the range. `null` when no channel in scope reports this metric."
          },
          "previous": {
            "type": [
              "number",
              "null"
            ],
            "description": "Value for the previous range."
          },
          "change": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent change from `previous` to `value`, rounded to 2 decimals. `null` when either is `null` or `previous` is 0."
          }
        }
      },
      "AnalyticsDateRange": {
        "type": "object",
        "description": "Calendar days in the API key user's time zone (both ends included).",
        "properties": {
          "start": {
            "type": "string",
            "format": "date"
          },
          "end": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "AnalyticsAccountRef": {
        "type": "object",
        "description": "Identity of a channel in an analytics row.",
        "properties": {
          "social_account_key": {
            "type": "string",
            "description": "Stable analytics key of the channel. For a connected channel it is the social account id."
          },
          "platform": {
            "$ref": "#/components/schemas/Platform"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "username": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "connected",
              "disconnected",
              "token_expired",
              null
            ],
            "description": "Current connection status. `null` when the channel is no longer in the workspace."
          }
        }
      },
      "AnalyticsTopPost": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AnalyticsAccountRef"
          },
          {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "description": "Analytics publication id. Read its detail with `GET /analytics/publications/{publication}`."
              },
              "post_platform_id": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              },
              "post_id": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid",
                "description": "TryPost post, or `null` for a post made outside TryPost."
              },
              "origin": {
                "type": "string",
                "description": "`trypost` or `external`."
              },
              "content_type": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Analytics publication type (`text`, `image`, `video`, ...)."
              },
              "availability": {
                "type": "string"
              },
              "published_at": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "When the network published it, UTC, `Y-m-d H:i:s`."
              },
              "permalink": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "excerpt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "preview_metadata": {
                "type": [
                  "object",
                  "null"
                ]
              },
              "reactions": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "comments": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          }
        ]
      },
      "AnalyticsSummary": {
        "type": "object",
        "description": "Totals for the range compared with the previous range. `posts` counts posts published in the range (made in TryPost or not). `engagement_rate` is a percent. `watch_time_minutes` and `average_watch_time_seconds` cover videos.",
        "properties": {
          "posts": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "net_followers": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "reactions": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "comments": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "engagement_rate": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "views": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "impressions": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "clicks": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "reposts": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "quotes": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "reach": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "shares": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "saves": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "watch_time_minutes": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "average_watch_time_seconds": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "follows_gained": {
            "$ref": "#/components/schemas/MetricComparison"
          },
          "followers": {
            "type": "object",
            "description": "Followers at the end of the range. Unlike the other metrics, `change` is the difference in followers, not a percent. `value` is `null` when a connected channel in scope has no follower count for the range yet.",
            "properties": {
              "value": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "previous": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "change": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          }
        }
      },
      "WorkspaceAnalyticsReport": {
        "type": "object",
        "properties": {
          "bounds": {
            "type": "object",
            "description": "First and last day with analytics data in scope (`null` when there is none).",
            "properties": {
              "min": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date"
              },
              "max": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date"
              }
            }
          },
          "range": {
            "$ref": "#/components/schemas/AnalyticsDateRange"
          },
          "previous_range": {
            "$ref": "#/components/schemas/AnalyticsDateRange"
          },
          "summary": {
            "$ref": "#/components/schemas/AnalyticsSummary"
          },
          "followers": {
            "type": "object",
            "properties": {
              "total": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "`null` when a connected channel in scope has no follower count for the range yet."
              },
              "accounts": {
                "type": "array",
                "items": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/AnalyticsAccountRef"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "social_account_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "uuid"
                        },
                        "network": {
                          "type": "string"
                        },
                        "value": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Followers at the end of the range."
                        },
                        "growth": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Followers gained between the first and last snapshot of the range."
                        },
                        "net": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Net followers gained in the range, when the network reports it."
                        },
                        "provenance": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  ]
                }
              },
              "series": {
                "type": "array",
                "description": "One point per day: follower count of each channel, keyed by `social_account_key`.",
                "items": {
                  "type": "object",
                  "properties": {
                    "date": {
                      "type": "string",
                      "format": "date"
                    },
                    "accounts": {
                      "type": "object",
                      "additionalProperties": {
                        "type": [
                          "integer",
                          "null"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "posts": {
            "type": "object",
            "properties": {
              "resolution": {
                "type": "string",
                "enum": [
                  "daily",
                  "weekly",
                  "monthly"
                ],
                "description": "Daily up to 14 days, weekly up to 90 days, monthly beyond. Weeks start on the API key user's start of week."
              },
              "accounts": {
                "type": "array",
                "items": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/AnalyticsAccountRef"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer",
                          "description": "Posts published in the range."
                        }
                      }
                    }
                  ]
                },
                "description": "Channels with at least one post in the range."
              },
              "buckets": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "start": {
                      "type": "string",
                      "format": "date"
                    },
                    "end": {
                      "type": "string",
                      "format": "date"
                    },
                    "accounts": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "integer"
                      },
                      "description": "Posts per channel, keyed by `social_account_key`."
                    },
                    "total": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "top_posts": {
            "type": "object",
            "description": "Up to 5 posts of the range with the most reactions, and up to 5 with the most comments.",
            "properties": {
              "reactions": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AnalyticsTopPost"
                }
              },
              "comments": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AnalyticsTopPost"
                }
              }
            }
          },
          "performance": {
            "type": "array",
            "description": "One row per channel with at least one post in the range, with each metric compared with the previous range.",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/AnalyticsAccountRef"
                },
                {
                  "type": "object",
                  "properties": {
                    "posts": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "reactions": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "comments": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "engagement_rate": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "reposts": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "impressions": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "clicks": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "views": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "shares": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "saves": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "follows_gained": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "reach": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "watch_time_minutes": {
                      "$ref": "#/components/schemas/MetricComparison"
                    },
                    "average_watch_time_seconds": {
                      "$ref": "#/components/schemas/MetricComparison"
                    }
                  }
                }
              ]
            }
          },
          "coverage": {
            "type": "array",
            "description": "How far back analytics have been collected for each connected channel. Each channel can have one row per collector.",
            "items": {
              "type": "object",
              "properties": {
                "social_account_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "collector": {
                  "type": "string",
                  "enum": [
                    "publication_backfill",
                    "publication_discovery"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "running",
                    "complete",
                    "partial",
                    "provider_limited",
                    "failed"
                  ]
                },
                "target_since": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "ISO 8601, UTC, with microseconds (`2026-04-11T00:00:00.000000Z`)."
                },
                "oldest_reached_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "ISO 8601, UTC, with microseconds (`2026-04-11T00:00:00.000000Z`)."
                },
                "high_watermark_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "ISO 8601, UTC, with microseconds (`2026-04-11T00:00:00.000000Z`)."
                },
                "last_success_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "ISO 8601, UTC, with microseconds (`2026-04-11T00:00:00.000000Z`)."
                },
                "last_error_category": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          }
        }
      },
      "ChannelInsightsFilters": {
        "type": "object",
        "description": "The filters the server applied, after defaults.",
        "properties": {
          "range": {
            "type": "string",
            "enum": [
              "7d",
              "30d",
              "mtd",
              "custom"
            ]
          },
          "start": {
            "type": "string",
            "format": "date"
          },
          "end": {
            "type": "string",
            "format": "date"
          },
          "period": {
            "type": "string",
            "enum": [
              "current",
              "previous"
            ]
          },
          "sort": {
            "type": "string",
            "description": "The sort used: the requested one when the channel reports that metric, else the first sortable metric it reports."
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "untagged": {
            "type": "boolean"
          },
          "types": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContentType"
            }
          }
        }
      },
      "ChannelInsights": {
        "type": "object",
        "properties": {
          "filters": {
            "$ref": "#/components/schemas/ChannelInsightsFilters"
          },
          "available_metrics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Metrics this channel reports, in display order (`followers`, `net_followers`, `posts`, `reactions`, `comments`, `engagement_rate`, `views`, `impressions`, `shares`, `reposts`, `quotes`, `saves`, `clicks`, `follows_gained`, `reach`, `watch_time_minutes`, `average_watch_time_seconds`)."
          },
          "summary": {
            "$ref": "#/components/schemas/WorkspaceAnalyticsReport",
            "description": "The workspace report shape, limited to this channel. Labels, untagged and types narrow the post metrics; followers stay account-wide."
          },
          "metric_series": {
            "type": "object",
            "description": "Per-bucket series for the range and the previous range. `posts`, `reach`, `views`, `impressions` and `profile_visits` are totals of the posts published in each bucket, not daily account totals. `followers` is the count at the end of each bucket; `net_followers` is cumulative from the start of the range.",
            "properties": {
              "resolution": {
                "type": "string",
                "enum": [
                  "daily",
                  "weekly"
                ],
                "description": "Daily up to 92 days, weekly beyond (weeks start on the API key user's start of week)."
              },
              "metrics": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "posts",
                    "followers",
                    "net_followers",
                    "reach",
                    "views",
                    "impressions",
                    "profile_visits"
                  ]
                }
              },
              "range": {
                "$ref": "#/components/schemas/AnalyticsDateRange"
              },
              "previous_range": {
                "$ref": "#/components/schemas/AnalyticsDateRange"
              },
              "current": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "start": {
                      "type": "string",
                      "format": "date"
                    },
                    "end": {
                      "type": "string",
                      "format": "date"
                    },
                    "values": {
                      "type": "object",
                      "additionalProperties": {
                        "type": [
                          "number",
                          "null"
                        ]
                      },
                      "description": "Value of each metric in `metrics` for the bucket."
                    }
                  }
                }
              },
              "previous": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "start": {
                      "type": "string",
                      "format": "date"
                    },
                    "end": {
                      "type": "string",
                      "format": "date"
                    },
                    "values": {
                      "type": "object",
                      "additionalProperties": {
                        "type": [
                          "number",
                          "null"
                        ]
                      },
                      "description": "Value of each metric in `metrics` for the bucket."
                    }
                  }
                }
              },
              "totals": {
                "type": "object",
                "properties": {
                  "current": {
                    "type": "object",
                    "additionalProperties": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  },
                  "previous": {
                    "type": "object",
                    "additionalProperties": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                }
              },
              "growth": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Monthly follower growth rate for the last 12 months. Ignores the range and the post filters. `null` until TryPost has at least two daily follower counts for the channel.",
                "properties": {
                  "range": {
                    "$ref": "#/components/schemas/AnalyticsDateRange"
                  },
                  "months": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "month": {
                          "type": "string",
                          "examples": [
                            "2026-10"
                          ]
                        },
                        "start": {
                          "type": "string",
                          "format": "date"
                        },
                        "end": {
                          "type": "string",
                          "format": "date"
                        },
                        "followers": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "rate": {
                          "type": [
                            "number",
                            "null"
                          ]
                        }
                      }
                    }
                  },
                  "latest": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Latest non-null monthly growth rate, in percent."
                  },
                  "previous": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Previous non-null monthly growth rate, in percent."
                  }
                }
              }
            }
          }
        }
      },
      "ChannelPostPerformance": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Analytics publication id."
          },
          "rank": {
            "type": "integer",
            "description": "Position by the `sort` metric, starting at 1."
          },
          "post_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "TryPost post, or `null` for a post made outside TryPost."
          },
          "excerpt": {
            "type": [
              "string",
              "null"
            ]
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "permalink": {
            "type": [
              "string",
              "null"
            ]
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601, UTC."
          },
          "content_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Analytics publication type (`text`, `image`, `video`, ...)."
          },
          "metrics": {
            "type": "object",
            "description": "`null` for a metric the network does not report. `engagement_rate` is a percent.",
            "properties": {
              "reactions": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "comments": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "engagement_rate": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "views": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "impressions": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "shares": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "reposts": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "quotes": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "saves": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "clicks": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "follows_gained": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "reach": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "watch_time_minutes": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "average_watch_time_seconds": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          }
        }
      },
      "Signature": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "content": {
            "type": "string",
            "description": "Text inserted in the composer when the signature is picked."
          },
          "created_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-09-01 10:00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-09-01 10:00:00"
            ]
          }
        }
      },
      "Workspace": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-05-04 12:00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "description": "UTC, format `Y-m-d H:i:s`.",
            "examples": [
              "2026-09-30 08:15:00"
            ]
          },
          "me": {
            "type": "object",
            "description": "What the API key's user may do in this workspace.",
            "properties": {
              "is_admin": {
                "type": "boolean"
              },
              "requires_approval": {
                "type": "boolean",
                "description": "Always `false` for admins."
              },
              "publishes_directly": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Key id (80 characters). Use it to delete the key."
          },
          "name": {
            "type": "string"
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-08T13:00:00+00:00"
            ]
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC. `null` never expires.",
            "examples": [
              "2026-12-31T23:59:59+00:00"
            ]
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-08T12:00:00+00:00"
            ]
          }
        }
      },
      "WebhookEventType": {
        "type": "string",
        "enum": [
          "post.created",
          "post.scheduled",
          "post.unscheduled",
          "post.published",
          "post.partially_published",
          "post.failed",
          "post.deleted"
        ],
        "description": "- `post.created`: a post was created. Its `data.status` is the status it was created with (`draft`, `scheduled`, `publishing` or `pending_approval`).\n- `post.scheduled`: an existing post was scheduled (for example a draft scheduled, or a request approved). A post created already scheduled sends only `post.created`.\n- `post.unscheduled`: a scheduled post went back to draft or to pending approval.\n- `post.published`: every destination was published.\n- `post.partially_published`: some destinations were published and others failed.\n- `post.failed`: publishing failed.\n- `post.deleted`: a post was deleted. Not sent for posts imported from the network or removed by disconnecting their channel. Its `data` is only `{id, workspace_id}`."
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "endpoint": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "enabled",
              "disabled",
              "paused"
            ],
            "description": "`paused` is set by TryPost after 5 failed deliveries in a row (the account owner is emailed). Set `status: enabled` to resume."
          },
          "last_sent_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-08T14:00:03+00:00"
            ]
          },
          "paused_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC."
          },
          "consecutive_failures": {
            "type": "integer"
          },
          "signing_secret": {
            "type": "string",
            "description": "Secret used to sign deliveries (`whsec_` and 32 characters). Only returned when you create, get or rotate the webhook.",
            "examples": [
              "whsec_4qXbV8kP2mT7nR1sW9yZ3cE6hJ0aL5dF"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-09-15T10:00:00+00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-08T14:00:03+00:00"
            ]
          }
        }
      },
      "WebhookLog": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Delivery id. It is also the `id` of the delivered body."
          },
          "event_type": {
            "$ref": "#/components/schemas/WebhookEventType"
          },
          "payload": {
            "type": "object",
            "description": "The body that was sent: `{id, type, data, created_at}`. `data` is the post (`id, workspace_id, user_id, status, created_via, content, scheduled_at, published_at, created_at, updated_at, author, workspace, labels, media, platforms`), or `{id, workspace_id}` for `post.deleted`."
          },
          "response_status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "response_body": {
            "type": [
              "string",
              "null"
            ],
            "description": "First 2000 bytes of the endpoint's answer, or the connection error."
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC."
          },
          "failed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC."
          },
          "attempts": {
            "type": "integer",
            "description": "Attempts made for this delivery (up to 3)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-08T14:00:02+00:00"
            ]
          }
        }
      },
      "RepurposeDestination": {
        "type": "object",
        "required": [
          "social_account_id",
          "content_type"
        ],
        "properties": {
          "social_account_id": {
            "type": "string",
            "format": "uuid",
            "description": "Social account of the workspace. Google Business is refused (its posts do not take video), and so is the source account."
          },
          "content_type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContentType"
              }
            ],
            "description": "Format to publish as. It must belong to the account's network and take video (for example `instagram_reel`, `tiktok_video`, `youtube_short`, `x_post`)."
          },
          "meta": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlatformMeta"
              }
            ],
            "description": "Per-network settings, with the same rules as a post's `platforms[].meta` (thread reply media by `url` is refused). On an active repurpose, the settings a network needs to publish are required, as on a scheduled post (for example TikTok `privacy_level`, Pinterest `board_id`, Discord `channel_id`, and a valid YouTube `description`)."
          }
        }
      },
      "Repurpose": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "source_social_account_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Instagram or Facebook account watched for new videos. `null` when that account was removed."
          },
          "source_account": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SocialAccount"
              },
              {
                "type": "null"
              }
            ],
            "description": "The source account, `null` when it was removed. Returned by `GET /repurposes` (and by `PUT` on an active repurpose)."
          },
          "source_format": {
            "type": "string",
            "enum": [
              "reel",
              "video",
              "story"
            ]
          },
          "publish_mode": {
            "type": "string",
            "enum": [
              "publish",
              "draft"
            ],
            "description": "`publish` publishes each new video to the destinations; `draft` saves it as drafts."
          },
          "destinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RepurposeDestination"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "active",
              "paused",
              "disabled"
            ]
          },
          "paused_reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "source_removed",
              "source_unavailable",
              "no_destinations",
              null
            ],
            "description": "Why TryPost paused it. `null` when it is not paused or you paused it."
          },
          "activated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC. Only videos posted after this instant are repurposed.",
            "examples": [
              "2026-10-01T09:00:00+00:00"
            ]
          },
          "last_polled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-08T13:45:00+00:00"
            ]
          },
          "next_poll_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-08T14:00:00+00:00"
            ]
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "published_items_count": {
            "type": "integer",
            "description": "Items with status `published`. Items saved as drafts (`drafted`) are not counted. Only in `GET /repurposes`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-09-30T18:00:00+00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-08T13:45:00+00:00"
            ]
          }
        }
      },
      "RepurposeItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "repurpose_id": {
            "type": "string",
            "format": "uuid"
          },
          "source_media_id": {
            "type": "string",
            "description": "Id of the video on the source network."
          },
          "source_permalink": {
            "type": [
              "string",
              "null"
            ]
          },
          "source_created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-07T21:10:00+00:00"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "published",
              "drafted",
              "skipped",
              "failed"
            ]
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "published_via_trypost",
              "media_url_missing",
              "download_failed",
              "post_creation_failed",
              "no_usable_destinations",
              null
            ],
            "description": "Why it was skipped or failed. `published_via_trypost`: the video was posted by TryPost, so it is not repurposed again."
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "posts": {
            "type": "array",
            "description": "Posts created for this video, with the status of each destination.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "platforms": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "platform": {
                        "$ref": "#/components/schemas/Platform"
                      },
                      "status": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-07T21:15:00+00:00"
            ]
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601, UTC.",
            "examples": [
              "2026-10-07T21:16:30+00:00"
            ]
          }
        }
      },
      "ContentTypeListing": {
        "type": "object",
        "description": "Media and publishing rules of one content type.",
        "properties": {
          "value": {
            "$ref": "#/components/schemas/ContentType"
          },
          "label": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "max_media_count": {
            "type": "integer"
          },
          "min_media_count": {
            "type": "integer"
          },
          "requires_media": {
            "type": "boolean"
          },
          "accept_images": {
            "type": "boolean"
          },
          "accept_videos": {
            "type": "boolean"
          },
          "accept_documents": {
            "type": "boolean"
          },
          "accepts_gif": {
            "type": "boolean"
          },
          "accepts_mov": {
            "type": "boolean"
          },
          "forbids_mixed_media": {
            "type": "boolean",
            "description": "Images and videos cannot be mixed in one post."
          },
          "max_video_duration_sec": {
            "type": [
              "integer",
              "null"
            ]
          },
          "max_image_bytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "max_video_bytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "max_document_bytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "aspect_ratio_min": {
            "type": [
              "number",
              "null"
            ],
            "description": "Image width / height."
          },
          "aspect_ratio_max": {
            "type": [
              "number",
              "null"
            ]
          },
          "video_aspect_ratio_min": {
            "type": [
              "number",
              "null"
            ]
          },
          "video_aspect_ratio_max": {
            "type": [
              "number",
              "null"
            ]
          },
          "auto_fits_image": {
            "type": "boolean",
            "description": "Images outside the aspect ratio are fitted instead of refused."
          },
          "supports_alt_text": {
            "type": "boolean"
          },
          "supports_user_tags": {
            "type": "boolean",
            "description": "Instagram user tags (`media[].meta.user_tags`)."
          },
          "supports_video_cover": {
            "type": "boolean",
            "description": "A video cover frame (`media[].meta.cover_offset_ms`)."
          },
          "image_min_width": {
            "type": [
              "integer",
              "null"
            ]
          },
          "image_min_height": {
            "type": [
              "integer",
              "null"
            ]
          },
          "image_max_width": {
            "type": [
              "integer",
              "null"
            ]
          },
          "image_max_height": {
            "type": [
              "integer",
              "null"
            ]
          },
          "captionless": {
            "type": "boolean",
            "description": "No text is sent (Instagram and Facebook stories), so the text is not measured for length or hashtags."
          },
          "document_must_be_alone": {
            "type": "boolean",
            "description": "A document (PDF) must be the only media of the post."
          },
          "supports_thread_replies": {
            "type": "boolean",
            "description": "`meta.thread_replies` is accepted (X, Bluesky, Mastodon)."
          },
          "max_thread_replies": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "PlatformContentTypes": {
        "type": "object",
        "properties": {
          "platform": {
            "$ref": "#/components/schemas/Platform"
          },
          "label": {
            "type": "string"
          },
          "max_content_length": {
            "type": "integer",
            "description": "Text limit of the network in characters (code points). An X account with long posts gets 25000: read `max_content_length` on the social account."
          },
          "max_hashtags": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Most hashtags a post may carry (5 on Instagram), checked when the post is saved. `null` is no limit."
          },
          "alt_text_max_length": {
            "type": [
              "integer",
              "null"
            ]
          },
          "required_meta": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "`meta` keys needed to schedule or publish (TikTok `privacy_level`, Pinterest `board_id`, Discord `channel_id`). Settings that depend on others (a Google Business event) or that the text can stand in for (a YouTube title) are not listed."
          },
          "recommended_content_length": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Suggested text length for the network."
          },
          "allowed_media_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "image",
                "video",
                "document"
              ]
            }
          },
          "default_content_type": {
            "$ref": "#/components/schemas/ContentType"
          },
          "content_types": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContentTypeListing"
            }
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing, invalid, revoked or expired API key. Bodies: `Unauthenticated.` (no key, or a key that is invalid or revoked), `Token expired.` (past its `expires_at`), `Token not found.` and `No workspace selected.` (the key is no longer bound to a workspace).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            },
            "example": {
              "message": "Unauthenticated."
            }
          }
        }
      },
      "Forbidden": {
        "description": "The request is not allowed. API keys work only for workspace admins (the account owner or a member marked as admin): otherwise every request returns `Insufficient workspace permissions.`. Other bodies: `Workspace access denied.` (the key's user left the workspace) and `Personal access token required.` (an MCP OAuth token was sent) and `This action is unauthorized.` (the note belongs to another member).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            }
          }
        }
      },
      "NotFound": {
        "description": "The resource does not exist in this workspace.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            }
          }
        }
      },
      "ValidationError": {
        "description": "Validation failed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ValidationErrorBody"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit exceeded. Limits: 60 requests per minute per workspace.",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait before retrying.",
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RateLimitErrorBody"
            }
          }
        }
      },
      "Conflict": {
        "description": "Another change to this post or its channel's queue is in progress. Retry.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "TryPost Cloud only: the workspace's account has no active subscription or trial. Body: `{\"message\": \"Active subscription required.\"}`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            },
            "example": {
              "message": "Active subscription required."
            }
          }
        }
      }
    },
    "parameters": {
      "PostId": {
        "name": "post",
        "in": "path",
        "required": true,
        "description": "Post id. A post of another workspace returns `404`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41"
      },
      "NoteId": {
        "name": "note",
        "in": "path",
        "required": true,
        "description": "Note id. It must belong to the post.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9d3c2a10-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
      },
      "AccountId": {
        "name": "account",
        "in": "path",
        "required": true,
        "description": "Social account (channel) id. An account of another workspace returns `404`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54"
      },
      "IdeaId": {
        "name": "idea",
        "in": "path",
        "required": true,
        "description": "Idea id. An idea of another workspace returns `404`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9e2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
      },
      "IdeaStageId": {
        "name": "ideaStage",
        "in": "path",
        "required": true,
        "description": "Idea stage id. A stage of another workspace returns `404`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9e1a2b3c-4d5e-4f6a-8b7c-9d0e1f2a3b4c"
      },
      "PublicationId": {
        "name": "publication",
        "in": "path",
        "required": true,
        "description": "Analytics publication id (`id` of a top post or of a channel post performance row).",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9d4a0b1c-2d3e-4f5a-8b6c-7d8e9f0a1b2c"
      },
      "LabelId": {
        "name": "label",
        "in": "path",
        "required": true,
        "description": "Label id. A label of another workspace returns `404`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f"
      },
      "SignatureId": {
        "name": "signature",
        "in": "path",
        "required": true,
        "description": "Signature id. A signature of another workspace returns `404`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
      },
      "ApiKeyId": {
        "name": "apiToken",
        "in": "path",
        "required": true,
        "description": "API key id, as returned by `GET /api-keys` (an 80-character string, not a UUID).",
        "schema": {
          "type": "string"
        },
        "example": "4f1d8c2b7e9a03c6d5b8e1f2a3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0"
      },
      "WebhookId": {
        "name": "webhook",
        "in": "path",
        "required": true,
        "description": "Webhook id. A webhook of another workspace returns `404`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e"
      },
      "WebhookLogId": {
        "name": "webhookLog",
        "in": "path",
        "required": true,
        "description": "Delivery log id. It must belong to the webhook in the path.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9b2c3d50-6a7b-4c8d-9e0f-1a2b3c4d5e6f"
      },
      "RepurposeId": {
        "name": "repurpose",
        "in": "path",
        "required": true,
        "description": "Repurpose id. A repurpose of another workspace returns `404`.",
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "example": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
      }
    }
  }
}
