{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/shapelessai/json-schema/shapelessai-post-schema.json",
  "title": "Post",
  "x-generated": "2026-11-11",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/shapelessai-openapi.json#/components/schemas/Post",
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "connectionId": {
      "type": [
        "string",
        "null"
      ]
    },
    "platform": {
      "type": [
        "string",
        "null"
      ]
    },
    "postText": {
      "type": "string"
    },
    "mediaKeys": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "scheduledAt": {
      "type": "string",
      "format": "date-time"
    },
    "status": {
      "type": "string",
      "enum": [
        "proposed",
        "scheduled",
        "publishing",
        "published",
        "handoff",
        "failed",
        "canceled"
      ]
    },
    "settings": {
      "type": [
        "object",
        "null"
      ]
    },
    "firstComment": {
      "type": [
        "string",
        "null"
      ]
    },
    "firstCommentUrl": {
      "type": [
        "string",
        "null"
      ],
      "description": "Where the first comment landed, once it did."
    },
    "firstCommentError": {
      "type": [
        "string",
        "null"
      ],
      "description": "Set when the post published but its first comment did not."
    },
    "publishedLocation": {
      "type": [
        "string",
        "null"
      ]
    },
    "error": {
      "type": [
        "string",
        "null"
      ]
    },
    "handoffNote": {
      "type": [
        "string",
        "null"
      ]
    },
    "publishNote": {
      "type": [
        "string",
        "null"
      ],
      "description": "Set when the post is live but not exactly as sent, with the platform's reason (for example YouTube refused the designed thumbnail until the channel verifies a phone number)."
    },
    "rationale": {
      "type": [
        "string",
        "null"
      ]
    },
    "inspiration": {
      "anyOf": [
        {
          "$ref": "#/$defs/PostInspiration"
        },
        {
          "type": "null"
        }
      ]
    },
    "metrics": {
      "type": [
        "object",
        "null"
      ]
    },
    "cover": {
      "type": [
        "object",
        "null"
      ],
      "description": "What the feed shows before the video plays. Null without a video.",
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "designed",
            "frame",
            "platform"
          ],
          "description": "designed: our thumbnail is uploaded as the cover (YouTube, LinkedIn, Facebook, Instagram). frame: a frame of the video at atMs (TikTok). platform: the platform picks its own frame."
        },
        "url": {
          "type": "string",
          "description": "The cover image, signed for 48 hours."
        },
        "thumbnailKey": {
          "type": [
            "string",
            "null"
          ],
          "description": "The designed thumbnail's media key."
        },
        "atMs": {
          "type": [
            "number",
            "null"
          ],
          "description": "TikTok's cover frame, in milliseconds."
        }
      }
    }
  },
  "required": [
    "id",
    "postText",
    "scheduledAt",
    "status"
  ],
  "$defs": {
    "PostInspiration": {
      "type": "object",
      "description": "What the post was made from: the predicted half of predicted-vs-actual. A malformed one is dropped, never a 400. A post made from a reference carries kind reference-post, the member id from GET /api/v1/references and the mode.",
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "format-card",
            "topical-story",
            "reference-post",
            "brand"
          ]
        },
        "id": {
          "type": "string",
          "maxLength": 200,
          "description": "The source's own id, e.g. platform:post_id for a reference post."
        },
        "lane": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "url": {
          "type": "string"
        },
        "mode": {
          "type": "string",
          "enum": [
            "clone",
            "format",
            "inspiration"
          ]
        },
        "memberId": {
          "type": "string",
          "description": "The reference member it was made from."
        }
      },
      "required": [
        "kind",
        "id"
      ]
    }
  }
}