{
  "openapi": "3.1.0",
  "info": {
    "title": "Autoadify API",
    "version": "1.0.0",
    "description": "Schedule and publish social posts, manage your media library and more."
  },
  "servers": [
    {
      "url": "https://api.autoadify.com/v1"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "The API key making the request."
    },
    {
      "name": "Channels",
      "description": "Connected social accounts."
    },
    {
      "name": "Posts",
      "description": "Schedule, publish and manage posts."
    },
    {
      "name": "Media",
      "description": "The media library."
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "summary": "Get current key",
        "description": "The organization, plan, scopes, channel limits and remaining quota of the API key making the request.\n\nRequires the `read` scope.",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "The key and its organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/channels": {
      "get": {
        "summary": "List channels",
        "description": "The connected social channels this key can post to, with each channel's posting rules. Keys limited to some channels only see those.\n\nRequires the `read` scope.",
        "tags": [
          "Channels"
        ],
        "responses": {
          "200": {
            "description": "Channels.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChannelList"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/posts": {
      "get": {
        "summary": "List posts",
        "description": "Posts newest first, with per-channel status, live URLs and errors.\n\nRequires the `read` scope.",
        "tags": [
          "Posts"
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "publishing",
                "published",
                "failed"
              ]
            }
          },
          {
            "name": "channelId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Only posts that include this channel."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only posts scheduled at or after this instant."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only posts scheduled before this instant."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "nextCursor from the previous page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of posts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostPage"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid query.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create post",
        "description": "Schedules a post to one or more channels, or publishes it now when `publishAt` is omitted (it goes out within about a minute). Validates platform rules up front: media requirements, TikTok privacy, Reddit subreddit.\n\nRequires the `publish` scope.",
        "tags": [
          "Posts"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePostRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The post, scheduled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The same post was created in the last 5 minutes (`duplicate_post`, with `details.postId`), or the plan's monthly post limit is reached (`limit_reached`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid body or a platform rule isn't met.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/posts/{id}": {
      "get": {
        "summary": "Get post",
        "description": "One post with its status on every channel.\n\nRequires the `read` scope.",
        "tags": [
          "Posts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Post id."
          }
        ],
        "responses": {
          "200": {
            "description": "The post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found, or not visible to this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update post",
        "description": "Edits a scheduled post's text, per-platform text or publish time.\n\nRequires the `publish` scope.",
        "tags": [
          "Posts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Post id."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePostRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated post.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The post isn't scheduled any more (`conflict`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete post",
        "description": "Cancels a scheduled post, or removes a published or failed one from Autoadify. Never deletes a post that is live on a platform.\n\nRequires the `publish` scope.",
        "tags": [
          "Posts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Post id."
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostDeleted"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The post is publishing right now (`conflict`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/media": {
      "get": {
        "summary": "List media",
        "description": "Ready files in the media library, newest first.\n\nRequires the `read` scope.",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "image",
                "video",
                "document",
                "media"
              ]
            },
            "description": "media = anything a post can carry (images, GIFs, videos)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Search file names, alt text and AI descriptions."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "nextCursor from the previous page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of media.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaPage"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/media/import": {
      "post": {
        "summary": "Import media from URL",
        "description": "Downloads an image (JPEG, PNG, WEBP, GIF, max 50 MB), video (MP4, MOV, WEBM, max 200 MB) or document from a public URL into the media library.\n\nRequires the `publish` scope.",
        "tags": [
          "Media"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportMediaRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The imported file, ready to attach.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Media"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The organization's 5 GB of storage is full (`limit_reached`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Unreachable, private, too large or unsupported file.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/media/uploads": {
      "post": {
        "summary": "Create upload",
        "description": "Starts an upload of a local file. PUT the bytes to the returned `upload.url` with `upload.headers` within 15 minutes, then call Complete upload.\n\nRequires the `publish` scope.",
        "tags": [
          "Media"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUploadRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "A pending media item and its upload URL.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaUpload"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Storage full (`limit_reached`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Unsupported type or too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/media/{id}": {
      "get": {
        "summary": "Get media",
        "description": "One media item.\n\nRequires the `read` scope.",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Media id."
          }
        ],
        "responses": {
          "200": {
            "description": "The media item.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Media"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete media",
        "description": "Permanently deletes a file. Refused while it's attached to a post that hasn't been published yet.\n\nRequires the `publish` scope.",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Media id."
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Attached to a scheduled post (`conflict`, with `details.postId`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/media/{id}/complete": {
      "post": {
        "summary": "Complete upload",
        "description": "Marks an upload ready once the file has been PUT. Safe to call again.\n\nRequires the `publish` scope.",
        "tags": [
          "Media"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Media id from Create upload."
          }
        ],
        "responses": {
          "200": {
            "description": "The media item, ready.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Media"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the scope this endpoint needs (`forbidden_scope`), or the plan has no API access (`plan_required`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Nothing has been uploaded yet (`conflict`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The uploaded file isn't a readable image.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit (`rate_limited`) or monthly quota (`quota_exceeded`) reached. `details.resetsAt` says when to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key from Autoadify → Settings → API & MCP, sent as `Authorization: Bearer aak_live_…`."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "unauthorized",
                  "forbidden_scope",
                  "plan_required",
                  "reauth_required",
                  "not_found",
                  "validation_failed",
                  "limit_reached",
                  "duplicate_post",
                  "conflict",
                  "rate_limited",
                  "quota_exceeded",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable; safe to show to a user."
              },
              "details": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {}
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "Me": {
        "type": "object",
        "properties": {
          "organization": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "plan": {
                "type": "string",
                "enum": [
                  "FREE",
                  "PRO",
                  "TEAM",
                  "ENTERPRISE"
                ]
              }
            },
            "required": [
              "id",
              "name",
              "plan"
            ],
            "additionalProperties": false
          },
          "key": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "prefix": {
                "type": "string",
                "description": "First characters of the key, for recognising it."
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "read",
                    "generate",
                    "publish"
                  ]
                }
              },
              "channels": {
                "anyOf": [
                  {
                    "type": "string",
                    "const": "all"
                  },
                  {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                ],
                "description": "\"all\", or the channel ids this key is limited to."
              },
              "expiresAt": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "name",
              "prefix",
              "scopes",
              "channels",
              "expiresAt"
            ],
            "additionalProperties": false
          },
          "quota": {
            "type": "object",
            "properties": {
              "requestsPerMinute": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "requestsPerMonth": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "null = unlimited."
              },
              "usedThisMonth": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "resetsAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": [
              "requestsPerMinute",
              "requestsPerMonth",
              "usedThisMonth",
              "resetsAt"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "organization",
          "key",
          "quota"
        ],
        "additionalProperties": false
      },
      "Channel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Use in channelIds when creating a post."
          },
          "platform": {
            "type": "string",
            "enum": [
              "INSTAGRAM",
              "FACEBOOK",
              "X",
              "LINKEDIN",
              "YOUTUBE",
              "TIKTOK",
              "PINTEREST",
              "REDDIT",
              "BLUESKY",
              "THREADS"
            ]
          },
          "platformName": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "username": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatarUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "disabled",
              "needs_reconnect"
            ],
            "description": "disabled: turned off in Autoadify. needs_reconnect: posts fail until the user reconnects it."
          },
          "rules": {
            "type": "object",
            "properties": {
              "requiresMedia": {
                "type": "boolean",
                "description": "No text-only posts (Instagram, TikTok, YouTube)."
              },
              "requiresVideo": {
                "type": "boolean",
                "description": "Only video (YouTube)."
              },
              "maxImages": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "description": "Extra images are dropped for this channel, not an error."
              },
              "maxChars": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Guide text length. Not enforced."
              },
              "requiredFields": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Extra fields a post to this channel needs, e.g. reddit.subreddit."
              }
            },
            "required": [
              "requiresMedia",
              "requiresVideo",
              "maxImages",
              "maxChars",
              "requiredFields"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "platform",
          "platformName",
          "name",
          "username",
          "avatarUrl",
          "status",
          "rules"
        ],
        "additionalProperties": false
      },
      "Post": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "publishing",
              "published",
              "failed"
            ]
          },
          "content": {
            "type": "string"
          },
          "scheduledAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "publishedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "type": "string",
            "description": "\"api\" for posts created here, \"app\" for the Autoadify app."
          },
          "channels": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "channelId": {
                  "type": "string"
                },
                "platform": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "scheduled",
                    "publishing",
                    "published",
                    "failed"
                  ]
                },
                "content": {
                  "description": "This channel's own text, or null when it uses the post's content.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "platformPostId": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "url": {
                  "description": "Live post URL, when the platform's URL can't be built from platformPostId.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "publishedAt": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "date-time"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "error": {
                  "description": "Why this channel failed.",
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "channelId",
                "platform",
                "status",
                "content",
                "platformPostId",
                "url",
                "publishedAt",
                "error"
              ],
              "additionalProperties": false
            }
          },
          "media": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "url": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "id",
                "type",
                "url"
              ],
              "additionalProperties": false
            }
          },
          "reddit": {
            "type": "object",
            "properties": {
              "subreddit": {
                "type": "string"
              },
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "subreddit",
              "title"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "status",
          "content",
          "scheduledAt",
          "publishedAt",
          "createdAt",
          "source",
          "channels",
          "media"
        ],
        "additionalProperties": false
      },
      "Media": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Use in mediaIds when creating a post."
          },
          "type": {
            "type": "string",
            "enum": [
              "image",
              "gif",
              "video",
              "document",
              "audio"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "ready",
              "failed"
            ]
          },
          "fileName": {
            "type": [
              "string",
              "null"
            ]
          },
          "mimeType": {
            "type": [
              "string",
              "null"
            ]
          },
          "sizeBytes": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "url": {
            "type": [
              "string",
              "null"
            ]
          },
          "thumbnailUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "width": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "height": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "durationSeconds": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ]
          },
          "altText": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "description": "What the file shows, from Autoadify's vision pass; null until it has run.",
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "type",
          "status",
          "fileName",
          "mimeType",
          "sizeBytes",
          "url",
          "thumbnailUrl",
          "width",
          "height",
          "durationSeconds",
          "altText",
          "description",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "MediaUpload": {
        "type": "object",
        "properties": {
          "media": {
            "$ref": "#/components/schemas/Media"
          },
          "upload": {
            "type": "object",
            "properties": {
              "method": {
                "type": "string",
                "const": "PUT"
              },
              "url": {
                "type": "string",
                "description": "One-time upload URL."
              },
              "headers": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "string"
                },
                "description": "Send exactly these headers with the PUT."
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "required": [
              "method",
              "url",
              "headers",
              "expiresAt"
            ],
            "additionalProperties": false
          },
          "next": {
            "type": "string"
          }
        },
        "required": [
          "media",
          "upload",
          "next"
        ],
        "additionalProperties": false
      },
      "ChannelList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Channel"
            }
          }
        },
        "required": [
          "data"
        ],
        "additionalProperties": false
      },
      "PostPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Post"
            }
          },
          "nextCursor": {
            "description": "Pass as cursor for the next page; null on the last page.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "data",
          "nextCursor"
        ],
        "additionalProperties": false
      },
      "MediaPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Media"
            }
          },
          "nextCursor": {
            "description": "Pass as cursor for the next page; null on the last page.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "data",
          "nextCursor"
        ],
        "additionalProperties": false
      },
      "Deleted": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "deleted": {
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "id",
          "deleted"
        ],
        "additionalProperties": false
      },
      "PostDeleted": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "deleted": {
            "type": "boolean",
            "const": true
          },
          "wasPublished": {
            "type": "boolean",
            "description": "true when the post was already live; it stays live on the platforms."
          }
        },
        "required": [
          "id",
          "deleted",
          "wasPublished"
        ],
        "additionalProperties": false
      },
      "CreatePostRequest": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63206,
            "description": "The post text, used on every channel unless contentByPlatform overrides it."
          },
          "channelIds": {
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Channel ids from list_channels / GET /v1/channels."
          },
          "publishAt": {
            "description": "When to publish, ISO 8601 with a UTC offset (e.g. 2026-10-12T09:00:00+05:30). Omit to publish now (goes out within about a minute).",
            "type": "string",
            "format": "date-time"
          },
          "mediaIds": {
            "default": [],
            "description": "Ids of READY images or videos from the media library, in display order.",
            "maxItems": 10,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "contentByPlatform": {
            "default": {},
            "description": "Per-platform text replacing content there, keyed by platform, e.g. { \"X\": \"short version\", \"LINKEDIN\": \"long version\" }.",
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 63206
            }
          },
          "reddit": {
            "description": "Required when posting to a Reddit channel.",
            "type": "object",
            "properties": {
              "subreddit": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Subreddit name without r/."
              },
              "title": {
                "description": "Post title; defaults to the first line of the text.",
                "type": "string",
                "maxLength": 300
              }
            },
            "required": [
              "subreddit"
            ]
          },
          "tiktok": {
            "description": "Required for TikTok unless the channel has saved posting defaults. privacyLevel: PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR or SELF_ONLY.",
            "type": "object",
            "properties": {
              "privacyLevel": {
                "type": "string"
              },
              "allowComment": {
                "type": "boolean"
              },
              "allowDuet": {
                "type": "boolean"
              },
              "allowStitch": {
                "type": "boolean"
              },
              "brandOrganicToggle": {
                "type": "boolean"
              },
              "brandContentToggle": {
                "type": "boolean"
              },
              "videoMadeWithAi": {
                "type": "boolean"
              }
            },
            "required": [
              "privacyLevel"
            ]
          }
        },
        "required": [
          "content",
          "channelIds"
        ]
      },
      "UpdatePostRequest": {
        "type": "object",
        "properties": {
          "content": {
            "description": "New text for every channel without its own override.",
            "type": "string",
            "minLength": 1,
            "maxLength": 63206
          },
          "publishAt": {
            "description": "New publish time, ISO 8601 with offset.",
            "type": "string",
            "format": "date-time"
          },
          "contentByPlatform": {
            "description": "Platform → override text; null removes that platform's override.",
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 63206
                },
                {
                  "type": "null"
                }
              ]
            }
          }
        }
      },
      "CreateUploadRequest": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "mimeType": {
            "type": "string",
            "description": "e.g. image/jpeg, image/png, video/mp4."
          },
          "fileSize": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "description": "Exact size in bytes; the upload is rejected if it differs."
          },
          "altText": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "fileName",
          "mimeType",
          "fileSize"
        ]
      },
      "ImportMediaRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Public http(s) URL of an image, video or PDF."
          },
          "fileName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "altText": {
            "description": "Accessibility text; published where the platform supports it.",
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "url"
        ]
      }
    }
  }
}
