MCP 서버

ViewPrinter

tech.viewprinter/viewprinter
마케팅 및 광고 소셜 미디어 공개 · 연결 가능 MCP 2025-11-25

이 MCP로 할 수 있는 일

Connects social accounts and schedules, updates, cancels, and measures posts across TikTok, Instagram, Facebook, YouTube, and X.

accounts_connect
Connect a social account
Connect a social account. Opens the platform in the person's browser so they can sign in and approve access — that part cannot happen here, because it needs their session and their consent. Call it again after they finish and it reports the connected account. With `invite`, the link is for someone else instead — a friend or family member who will create a brand-new account and connect it, with no login of their own here. They get a page showing the profile to set up (picture, username, name, bio) with copy buttons, the steps to switch Instagram to a Creator account, and a Connect button. Give the person the `url`. Calling again with the same platform and username returns the same invite, updated with whatever profile fields are given, and its status — so that is also how to check whether they have finished. Upload the profile picture first with media_upload, and pass its id once the PUT succeeds.
외부 접근 가능 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['platform'], 'properties': {'invite': {'type': 'object', 'required': ['username'], 'properties': {'bio': {'type': 'string', 'maxLength': 150, 'description': 'The profile bio. Instagram caps it at 150 characters.'}, 'username': {'type': 'string', 'maxLength': 31, 'minLength': 1, 'description': 'The handle they should register, without the @. Also what identifies this invite on a repeat call. Instagram allows letters, numbers, periods and underscores, up to 30.'}, 'display_name': {'type': 'string', 'maxLength': 64, 'description': 'The profile name shown above the bio.'}, 'avatar_media_id': {'type': 'string', 'description': 'An image uploaded with media_upload to use as the profile picture. The invite goes into the same workspace as the image.'}}, 'description': 'Set to make a link for someone without a login here, who will create the account. Leave out to connect an account yourself.'}, 'platform': {'enum': ['tiktok', 'instagram', 'facebook', 'youtube', 'x'], 'type': 'string', 'description': 'Which platform to connect.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['platform', 'connected', 'status'], 'properties': {'url': {'type': 'string'}, 'invite': {'type': 'object', 'required': ['platform', 'username', 'displayName', 'bio', 'lastError', 'avatarUrl', 'connectedHandle', 'connected', 'id', 'createdAt'], 'properties': {'id': {'type': 'string'}, 'bio': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'platform': {'type': 'string'}, 'username': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'avatarUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'connected': {'type': 'boolean'}, 'createdAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'lastError': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'displayName': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'connectedHandle': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'status': {'type': 'string'}, 'platform': {'type': 'string'}, 'connected': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'platform', 'handle', 'displayName', 'status', 'refreshTokenExpiresAt', 'organizationId', 'avatarUrl', 'profileUrl', 'scopeCoverage'], 'properties': {'id': {'type': 'string'}, 'handle': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'status': {'type': 'string'}, 'platform': {'type': 'string'}, 'avatarUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'profileUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'displayName': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'scopeCoverage': {'anyOf': [{'type': 'object', 'required': ['granted', 'expected', 'held', 'missing'], 'properties': {'held': {'type': 'array', 'items': {'type': 'string'}}, 'granted': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'missing': {'type': 'array', 'items': {'type': 'string'}}, 'expected': {'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}}, 'additionalProperties': False}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}, 'refreshTokenExpiresAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}}}, 'additionalProperties': False}
accounts_list
List connected accounts
List every social account you can post to, across all your workspaces. Each account includes the workspace it belongs to and any groups it is in. Use the returned ids to name post destinations explicitly, or a group name to name several at once. metrics true adds how each account is performing — followers, posts, total likes and following, each with how far it moved over the period — and orders by followers, largest first. Numbers are as of the last sweep rather than live; every account carries the time it was measured, and one nobody has measured yet has no metrics at all rather than zeroes.
읽기 전용 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'period': {'enum': ['24h', '7d'], 'type': 'string', 'description': 'With metrics: the window every change is measured over. Defaults to 24h. A change is the difference against the last observation before the window opened, so it is null when there was none.'}, 'metrics': {'type': 'boolean', 'description': 'Include followers and how they moved. Defaults to false.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['accounts'], 'properties': {'accounts': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'platform', 'handle', 'displayName', 'status', 'refreshTokenExpiresAt', 'organizationId', 'avatarUrl', 'profileUrl', 'scopeCoverage', 'groups'], 'properties': {'id': {'type': 'string'}, 'groups': {'type': 'array', 'items': {'type': 'string'}}, 'handle': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'status': {'type': 'string'}, 'metrics': {'anyOf': [{'type': 'object', 'required': ['capturedAt', 'comparedTo', 'followers', 'posts', 'likes', 'following'], 'properties': {'likes': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'posts': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'followers': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'following': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'capturedAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'comparedTo': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}, {'type': 'null'}]}, 'platform': {'type': 'string'}, 'avatarUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'profileUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'displayName': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'scopeCoverage': {'anyOf': [{'type': 'object', 'required': ['granted', 'expected', 'held', 'missing'], 'properties': {'held': {'type': 'array', 'items': {'type': 'string'}}, 'granted': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'missing': {'type': 'array', 'items': {'type': 'string'}}, 'expected': {'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}}, 'additionalProperties': False}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}, 'refreshTokenExpiresAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}}}, 'additionalProperties': False}
groups_delete
Delete an account group
Remove a group. The accounts in it are not touched and stay connected — only the name and its membership go. Posts already scheduled through it are unaffected, because a post records the accounts rather than the group.
파괴적 작업 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'The group to remove, from groups_list.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['deleted'], 'properties': {'deleted': {'type': 'string'}}, 'additionalProperties': False}
groups_list
List account groups
Your named sets of accounts. Each group lists its members with the state of each, and how many of them need reconnecting — a post naming a group is refused outright if any member cannot publish, so check here before composing one. Use a group name with posts_save instead of listing account ids.
읽기 전용 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['groups'], 'properties': {'groups': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'name', 'description', 'members', 'needsReconnecting'], 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'members': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'platform', 'handle', 'displayName', 'status', 'refreshTokenExpiresAt', 'organizationId', 'avatarUrl', 'profileUrl', 'scopeCoverage'], 'properties': {'id': {'type': 'string'}, 'handle': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'status': {'type': 'string'}, 'platform': {'type': 'string'}, 'avatarUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'profileUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'displayName': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'scopeCoverage': {'anyOf': [{'type': 'object', 'required': ['granted', 'expected', 'held', 'missing'], 'properties': {'held': {'type': 'array', 'items': {'type': 'string'}}, 'granted': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'missing': {'type': 'array', 'items': {'type': 'string'}}, 'expected': {'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}}, 'additionalProperties': False}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}, 'refreshTokenExpiresAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}}, 'description': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'needsReconnecting': {'type': 'number'}}, 'additionalProperties': False}}}, 'additionalProperties': False}
groups_save
Save an account group
Create a group or change one. A group is a name for a set of accounts, so posts_save can take the name instead of every id. Found by name without regard to case: an existing group is updated (new_name renames it), and a new name creates one, which needs account_ids. account_ids is always the full membership afterwards, not a list to add. All the accounts must be in one workspace.
멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['name'], 'properties': {'name': {'type': 'string', 'description': 'The group, matched without regard to case. Created when there is none by this name.'}, 'new_name': {'type': 'string', 'description': 'Rename an existing group to this.'}, 'account_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'The complete membership, from accounts_list â\x80\x94 whatever is sent replaces what was there. Required to create a group; omit it to leave an existing groupâ\x80\x99s members alone.'}, 'description': {'type': 'string', 'description': 'What it is for, so it can be chosen without reading it.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['group', 'created'], 'properties': {'group': {'type': 'object', 'required': ['id', 'name', 'description', 'members', 'needsReconnecting'], 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'members': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'platform', 'handle', 'displayName', 'status', 'refreshTokenExpiresAt', 'organizationId', 'avatarUrl', 'profileUrl', 'scopeCoverage'], 'properties': {'id': {'type': 'string'}, 'handle': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'status': {'type': 'string'}, 'platform': {'type': 'string'}, 'avatarUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'profileUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'displayName': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'scopeCoverage': {'anyOf': [{'type': 'object', 'required': ['granted', 'expected', 'held', 'missing'], 'properties': {'held': {'type': 'array', 'items': {'type': 'string'}}, 'granted': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'missing': {'type': 'array', 'items': {'type': 'string'}}, 'expected': {'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}}, 'additionalProperties': False}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}, 'refreshTokenExpiresAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}}, 'description': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'needsReconnecting': {'type': 'number'}}, 'additionalProperties': False}, 'created': {'type': 'boolean'}}, 'additionalProperties': False}
media_delete
Delete a file
Remove a file and its stored bytes. This cannot be undone, and any post still using it will lose it.
파괴적 작업 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['deleted'], 'properties': {'deleted': {'type': 'boolean'}}, 'additionalProperties': False}
media_list
List uploaded media
Files uploaded in your workspaces, newest first, 50 at a time. Use these ids when attaching media to a post. Narrow with kind or search (words in the description), or pass media_id for one file. When nextCursor is not null, pass it as cursor for the next page.
읽기 전용 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'kind': {'enum': ['image', 'video', 'audio'], 'type': 'string', 'description': 'Only this kind of file.'}, 'limit': {'type': 'integer', 'maximum': 200, 'minimum': 1, 'description': 'How many to return. Defaults to 50.'}, 'cursor': {'type': 'string', 'description': 'nextCursor from the previous page, for the page after it.'}, 'search': {'type': 'string', 'description': 'Words in the description, ignoring case.'}, 'media_id': {'type': 'string', 'description': 'One file by id. Every other argument is ignored.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['media', 'nextCursor'], 'properties': {'media': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'kind', 'description', 'mimeType', 'byteSize', 'width', 'height', 'durationMs', 'organizationId', 'createdAt'], 'properties': {'id': {'type': 'string'}, 'kind': {'type': 'string'}, 'width': {'anyOf': [{'type': 'integer', 'maximum': 2147483647, 'minimum': -2147483648}, {'type': 'null'}]}, 'height': {'anyOf': [{'type': 'integer', 'maximum': 2147483647, 'minimum': -2147483648}, {'type': 'null'}]}, 'byteSize': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, 'mimeType': {'type': 'string'}, 'createdAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'durationMs': {'anyOf': [{'type': 'integer', 'maximum': 2147483647, 'minimum': -2147483648}, {'type': 'null'}]}, 'description': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}}, 'additionalProperties': False}}, 'nextCursor': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}}, 'additionalProperties': False}
media_save
Describe a file
Say what a file shows, in your own words. On a base image this is who is on camera — "a woman in her early twenties, blonde hair in a loose bun" — and a campaign reads it so the same person appears in every render instead of changing between them. Send null to clear it. Nothing else about a file can be changed here; what it is was read from the file itself.
멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id', 'description'], 'properties': {'id': {'type': 'string'}, 'description': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'description': 'The words, or null to remove the ones already there.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['media'], 'properties': {'media': {'type': 'object', 'required': ['id', 'kind', 'description', 'mimeType', 'byteSize', 'width', 'height', 'durationMs', 'organizationId', 'createdAt'], 'properties': {'id': {'type': 'string'}, 'kind': {'type': 'string'}, 'width': {'anyOf': [{'type': 'integer', 'maximum': 2147483647, 'minimum': -2147483648}, {'type': 'null'}]}, 'height': {'anyOf': [{'type': 'integer', 'maximum': 2147483647, 'minimum': -2147483648}, {'type': 'null'}]}, 'byteSize': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, 'mimeType': {'type': 'string'}, 'createdAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'durationMs': {'anyOf': [{'type': 'integer', 'maximum': 2147483647, 'minimum': -2147483648}, {'type': 'null'}]}, 'description': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}}, 'additionalProperties': False}}, 'additionalProperties': False}
media_upload
Start a media upload
Get a file into ViewPrinter, under an id you can pass to posts_save, media_save or anything else that takes a media id. If the person attached the file in this chat, or has it on their phone or computer, call this with no arguments, as an ordinary tool call — not from code, and without trying to send the file yourself. Apps that show widgets put an upload box under the call, which sends the file to ViewPrinter directly even when you have no network access: tell the person to use it. It takes one video or up to ten photos and posts their media ids to the chat, in order, when they are in. Where no box appears, give the person `upload_page`: any device, no sign-in, lasts an hour. Only if you hold the file yourself and can make HTTP requests (a terminal agent, a server), pass kind and mime_type and PUT the bytes to `url` with that Content-Type and no other headers. Apps that show widgets never get `url`: the upload box is the way there. Either way the file lands under `id` and is recorded as soon as it arrives. With the box or the page, wait for the person before using it.
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'kind': {'enum': ['image', 'video', 'audio'], 'type': 'string', 'description': 'What the file is. Only with mime_type, when you hold it.'}, 'mime_type': {'type': 'string', 'description': 'The exact Content-Type your PUT will send, e.g. video/mp4. Only with kind, when you hold the file.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id', 'upload_page'], 'properties': {'id': {'type': 'string'}, 'url': {'type': 'string'}, 'upload_page': {'type': 'string'}, 'expires_in_seconds': {'type': 'number'}}, 'additionalProperties': False}
platforms_list
List platform rules
What each platform accepts. Called with nothing, it lists every platform with the media kinds and counts it takes and its caption limit — enough to decide where a post can go. Name platforms to add their recommended sizes and durations, their options with what each one does, and the quirks that decide how a post is treated. Read this before scheduling rather than discovering the rules by being rejected.
읽기 전용 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Which platforms to describe in full. Omit for a short answer covering all of them. Naming only the platforms you are posting to keeps the reply small â\x80\x94 full detail for all of them is several times the size.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['platforms'], 'properties': {'platforms': {'type': 'array', 'items': {'type': 'object', 'required': ['platform', 'label', 'canConnect', 'canPublish', 'media', 'caption'], 'properties': {'label': {'type': 'string'}, 'media': {'anyOf': [{'type': 'object', 'required': ['text'], 'properties': {'text': {'type': 'boolean'}, 'image': {'type': 'object', 'required': ['max'], 'properties': {'max': {'type': 'number'}}, 'additionalProperties': False}, 'video': {'type': 'object', 'required': ['max'], 'properties': {'max': {'type': 'number'}}, 'additionalProperties': False}}, 'additionalProperties': False}, {'type': 'null'}]}, 'notes': {'type': 'array', 'items': {'type': 'string'}}, 'specs': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'label', 'kind', 'width', 'height', 'ratio'], 'properties': {'id': {'type': 'string'}, 'kind': {'type': 'string'}, 'note': {'type': 'string'}, 'label': {'type': 'string'}, 'ratio': {'type': 'string'}, 'width': {'type': 'number'}, 'height': {'type': 'number'}, 'formats': {'type': 'array', 'items': {'type': 'string'}}, 'maxBytes': {'type': 'number'}, 'maxSeconds': {'type': 'number'}}, 'additionalProperties': False}}, 'caption': {'anyOf': [{'type': 'object', 'required': ['label', 'max'], 'properties': {'max': {'type': 'number'}, 'label': {'type': 'string'}, 'extras': {'type': 'array', 'items': {'type': 'object', 'required': ['label', 'max'], 'properties': {'max': {'type': 'number'}, 'label': {'type': 'string'}}, 'additionalProperties': False}}}, 'additionalProperties': False}, {'type': 'null'}]}, 'options': {}, 'platform': {'type': 'string'}, 'canConnect': {'type': 'boolean'}, 'canPublish': {'type': 'boolean'}}, 'additionalProperties': False}}}, 'additionalProperties': False}
posts_list
List posts
Posts in your workspaces, newest first, one page at a time, each with the state of every destination it was sent to and the numbers it has earned so far. Call it to find one post (post_id), to check whether something published, and before changing or cancelling anything — posts_save takes a post_id from here. Numbers are as of the last sweep, and every destination carries the time it was measured — one nobody has measured yet has no metrics at all rather than zeroes. `trial` names an Instagram trial reel's graduation strategy, and is null for anything that is not one. A trial is shown to non-followers first, so its numbers come from a colder audience than an ordinary post's: compare trials with trials. Each row also carries `insights`: what the platform's own analytics said on that delivery, never summed across deliveries. reach (distinct accounts), totalWatchMs and avgWatchMs, replays, follows (gained from the post), completionRate and skipRate as fractions 0..1, `retention` — the full audience-retention curve as Facebook sends it, `points[i]` being the share still watching at i twentieths of the video and `bucketMs` one twentieth in milliseconds — and `breakdowns` such as clicks by type. retentionAt3s and retentionAtHalf are read off that curve, interpolated between buckets, so hooks can be ranked by how many viewers they held; null without a curve or a known video length. Null means the platform does not report it; a name listed in `unavailable` means it would have and refused this time. Compare watch time across platforms as totalWatchMs / views: Facebook averages per play and Instagram per viewer, so avgWatchMs is not comparable between them. Every filter is optional and they combine: a date range, statuses, platforms, accounts, groups and products by name, where the post came from, and a caption search. Pass nextCursor back as cursor for the next page; null means there is no more.
읽기 전용 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'by': {'enum': ['value', 'change'], 'type': 'string', 'description': 'With rank_by: the running total, or how much it moved over the period. Defaults to the total. Insights rank by value only.'}, 'to': {'type': 'string', 'description': 'ISO date or date-time. Only posts before this.'}, 'from': {'type': 'string', 'description': 'ISO date or date-time. Only posts that went out, or are due to, at or after this.'}, 'group': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Groups by name, from groups_list: posts to any of their accounts.'}, 'limit': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Posts per page. Defaults to 25.'}, 'order': {'enum': ['asc', 'desc'], 'type': 'string', 'description': 'Defaults to desc.'}, 'cursor': {'type': 'string', 'description': 'nextCursor from the previous page.'}, 'period': {'enum': ['24h', '7d'], 'type': 'string', 'description': "The window each figure's change is measured over. Defaults to 24h."}, 'search': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': 'Text the caption contains, ignoring case.'}, 'source': {'type': 'array', 'items': {'enum': ['web', 'mcp', 'api', 'campaign', 'external'], 'type': 'string'}, 'description': 'Where a post came from. external is one made on the platform itself and found afterwards.'}, 'status': {'type': 'array', 'items': {'enum': ['published', 'scheduled', 'draft', 'failed', 'cancelled'], 'type': 'string'}, 'description': 'published, scheduled, draft, failed or cancelled. A post matches when any of its destinations is in one of these states.'}, 'post_id': {'type': 'string', 'description': 'One post by id. The other filters are ignored.'}, 'product': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Products by name or id: posts to accounts linked to them.'}, 'rank_by': {'enum': ['views', 'likes', 'comments', 'shares', 'saves', 'reach', 'totalWatchMs', 'avgWatchMs', 'replays', 'follows', 'completionRate', 'retentionAt3s', 'retentionAtHalf'], 'type': 'string', 'description': 'Rank the matching posts by one figure of their best destination instead: any counter (views, likes, â\x80¦) or insight (reach, avgWatchMs, completionRate, retentionAt3s, retentionAtHalf, â\x80¦). Answers "which hooks held viewers" or "what is moving now". Ranks up to 500 matching posts; no cursor.'}, 'sort_by': {'enum': ['views', 'likes', 'comments', 'shares', 'saves', 'reach', 'totalWatchMs', 'replays', 'follows', 'when', 'updated', 'account'], 'type': 'string', 'description': 'A counter or insight (views, likes, â\x80¦), "when", "updated" or "account". Defaults to newest first.'}, 'platform': {'type': 'array', 'items': {'enum': ['tiktok', 'instagram', 'facebook', 'x', 'youtube', 'linkedin'], 'type': 'string'}}, 'account_id': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Accounts by id, from accounts_list.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['posts', 'nextCursor'], 'properties': {'posts': {'type': 'array', 'items': {'type': 'object', 'required': ['post', 'thumbnail', 'targets', 'totals', 'sums', 'happenedAt'], 'properties': {'post': {'type': 'object', 'required': ['id', 'status', 'content', 'scheduledAt', 'source', 'organizationId', 'createdAt'], 'properties': {'id': {'type': 'string'}, 'source': {'type': 'string'}, 'status': {'type': 'string'}, 'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'createdAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'scheduledAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}}, 'additionalProperties': False}, 'sums': {'type': 'object', 'required': ['reach', 'totalWatchMs', 'replays', 'follows'], 'propertyNames': {'enum': ['reach', 'totalWatchMs', 'replays', 'follows'], 'type': 'string'}, 'additionalProperties': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'totals': {'anyOf': [{'type': 'object', 'required': ['capturedAt', 'comparedTo', 'views', 'likes', 'comments', 'shares', 'saves'], 'properties': {'likes': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'saves': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'views': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'shares': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'comments': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'capturedAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'comparedTo': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}, {'type': 'null'}]}, 'targets': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'socialAccountId', 'status', 'externalUrl', 'publishedAt', 'lastError', 'post', 'account', 'trial', 'metrics', 'insights', 'thumbnail', 'finalizedAt', 'postedAt', 'promotedAt'], 'properties': {'id': {'type': 'string'}, 'post': {'type': 'object', 'required': ['id', 'status', 'content', 'scheduledAt', 'source', 'organizationId', 'createdAt'], 'properties': {'id': {'type': 'string'}, 'source': {'type': 'string'}, 'status': {'type': 'string'}, 'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'createdAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'scheduledAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}}, 'additionalProperties': False}, 'trial': {'anyOf': [{'enum': ['SS_PERFORMANCE', 'MANUAL'], 'type': 'string'}, {'type': 'null'}]}, 'status': {'type': 'string'}, 'account': {'type': 'object', 'required': ['id', 'platform', 'handle', 'displayName', 'status', 'refreshTokenExpiresAt', 'organizationId', 'avatarUrl', 'profileUrl', 'scopeCoverage'], 'properties': {'id': {'type': 'string'}, 'handle': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'status': {'type': 'string'}, 'platform': {'type': 'string'}, 'avatarUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'profileUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'displayName': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'scopeCoverage': {'anyOf': [{'type': 'object', 'required': ['granted', 'expected', 'held', 'missing'], 'properties': {'held': {'type': 'array', 'items': {'type': 'string'}}, 'granted': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'missing': {'type': 'array', 'items': {'type': 'string'}}, 'expected': {'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}}, 'additionalProperties': False}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}, 'refreshTokenExpiresAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'metrics': {'anyOf': [{'type': 'object', 'required': ['capturedAt', 'comparedTo', 'views', 'likes', 'comments', 'shares', 'saves'], 'properties': {'likes': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'saves': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'views': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'shares': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'comments': {'type': 'object', 'required': ['value', 'change'], 'properties': {'value': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'change': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, 'capturedAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'comparedTo': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}, {'type': 'null'}]}, 'insights': {'anyOf': [{'type': 'object', 'required': ['reach', 'totalWatchMs', 'avgWatchMs', 'replays', 'follows', 'completionRate', 'skipRate', 'retention', 'breakdowns', 'unavailable', 'retentionAt3s', 'retentionAtHalf'], 'properties': {'reach': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'null'}]}, 'follows': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'null'}]}, 'replays': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'null'}]}, 'skipRate': {'anyOf': [{'type': 'number', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'null'}]}, 'retention': {'anyOf': [{'type': 'object', 'required': ['points', 'bucketMs'], 'properties': {'points': {'type': 'array', 'items': {'type': 'number'}}, 'bucketMs': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, {'type': 'null'}]}, 'avgWatchMs': {'anyOf': [{'type': 'integer', 'maximum': 2147483647, 'minimum': -2147483648}, {'type': 'null'}]}, 'breakdowns': {'anyOf': [{'type': 'object', 'propertyNames': {'type': 'string'}, 'additionalProperties': {'type': 'object', 'propertyNames': {'type': 'string'}, 'additionalProperties': {'type': 'number'}}}, {'type': 'null'}]}, 'unavailable': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}]}, 'totalWatchMs': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'null'}]}, 'retentionAt3s': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}, 'completionRate': {'anyOf': [{'type': 'number', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'null'}]}, 'retentionAtHalf': {'anyOf': [{'type': 'number'}, {'type': 'null'}]}}, 'additionalProperties': False}, {'type': 'null'}]}, 'postedAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'lastError': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'thumbnail': {'anyOf': [{'type': 'object', 'required': ['id', 'kind'], 'properties': {'id': {'type': 'string'}, 'kind': {'type': 'string'}}, 'additionalProperties': False}, {'type': 'null'}]}, 'promotedAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'externalUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'finalizedAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'publishedAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'socialAccountId': {'type': 'string'}}, 'additionalProperties': False}, 'minItems': 1}, 'thumbnail': {'anyOf': [{'type': 'object', 'required': ['id', 'kind'], 'properties': {'id': {'type': 'string'}, 'kind': {'type': 'string'}}, 'additionalProperties': False}, {'type': 'null'}]}, 'happenedAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}}, 'additionalProperties': False}}, 'nextCursor': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}}, 'additionalProperties': False}
posts_save
Save a post
Create, change or cancel a post. This publishes: a new post is queued for every account named and goes out at scheduled_at, or as soon as possible without one. Do not tell anyone their post is saved or scheduled until this has returned successfully. No post_id creates a post. Name accounts with ids from accounts_list, or a group from groups_list for all of its members — the two combine, and a group is expanded now, so adding an account to it later does not add it to this post. Accounts must all be in one workspace. Attach media by id from media_list; a post is either a video or a set of images, never both. draft true holds it here without sending anything. With post_id, changes a post that has not gone out: caption, time, destinations, or draft state. account_ids and groups then replace the destination list entirely. draft false sends a draft. Setting scheduled_at on a post whose destinations failed queues the failed ones again and leaves the published ones alone — fix what made them fail first, usually by reconnecting. The caption and destinations can only change while nothing has published; after that only the time can, and new words mean a new post. With post_id and cancel true, stops it: destinations that have not started are cancelled, and any already being published cannot be recalled and come back in still_going. Safe to repeat. Publishing has to be enabled on the account; where it is not, a new post saves nothing at all and a draft is left as it was, and the answer says so. Cancelling works whether or not publishing is enabled.
파괴적 작업 외부 접근 가능
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'draft': {'type': 'boolean', 'description': 'True holds the post here: nothing is queued and nothing reaches any platform. On an existing post, false sends a draft and true returns a scheduled post to draft. Unrelated to the per-platform draft option, which uploads to the platform for the creator to finish.'}, 'cancel': {'type': 'boolean', 'description': 'With post_id: stop the post before it goes out.'}, 'groups': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Group names from groups_list, expanded to their members and combined with account_ids. Matched without regard to case.'}, 'content': {'type': 'string', 'description': 'The caption.'}, 'post_id': {'type': 'string', 'description': 'A post to change or cancel, from posts_list. Omit to create one.'}, 'media_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'New posts only. Files to attach, in order â\x80\x94 the slideshow order.'}, 'account_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Accounts to post to, from accounts_list. On a new post, optional when groups is given; naming neither is refused. On an existing post, replaces the destinations â\x80\x94 send every account you want.'}, 'scheduled_at': {'type': 'string', 'description': 'ISO 8601. Omit to send as soon as possible. A time in the past sends as soon as possible.'}, 'idempotency_key': {'type': 'string', 'description': 'New posts only. Reuse on retry to avoid posting twice; returns the original post.'}, 'platform_options': {'type': 'object', 'properties': {'x': {'type': 'object', 'properties': {}, 'additionalProperties': False}, 'tiktok': {'type': 'object', 'properties': {'draft': {'type': 'boolean'}, 'title': {'type': 'string', 'maxLength': 90}, 'isAigc': {'type': 'boolean'}, 'disableDuet': {'type': 'boolean'}, 'autoAddMusic': {'type': 'boolean'}, 'privacyLevel': {'enum': ['PUBLIC_TO_EVERYONE', 'MUTUAL_FOLLOW_FRIENDS', 'FOLLOWER_OF_CREATOR', 'SELF_ONLY'], 'type': 'string'}, 'disableStitch': {'type': 'boolean'}, 'disableComment': {'type': 'boolean'}, 'photoCoverIndex': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'brandContentToggle': {'type': 'boolean'}, 'brandOrganicToggle': {'type': 'boolean'}, 'videoCoverTimestampMs': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}}, 'additionalProperties': False}, 'youtube': {'type': 'object', 'properties': {'tags': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'privacy': {'enum': ['public', 'unlisted', 'private'], 'type': 'string'}, 'categoryId': {'type': 'string'}, 'madeForKids': {'type': 'boolean'}, 'containsSyntheticMedia': {'type': 'boolean'}}, 'additionalProperties': False}, 'facebook': {'type': 'object', 'properties': {}, 'additionalProperties': False}, 'instagram': {'type': 'object', 'properties': {'story': {'type': 'boolean'}, 'coverUrl': {'type': 'string', 'format': 'uri'}, 'trialReel': {'enum': ['SS_PERFORMANCE', 'MANUAL'], 'type': 'string'}, 'shareToFeed': {'type': 'boolean'}, 'thumbOffset': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'isAiGenerated': {'type': 'boolean'}}, 'additionalProperties': False}}, 'description': 'New posts only. Per-platform settings, keyed by platform. Only the keys shown are accepted â\x80\x94 an unknown key is refused rather than ignored. Call platforms_list for what each one does, its default, and which kind of post it applies to.'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {'post': {'type': 'object', 'required': ['id', 'status', 'content', 'scheduledAt', 'source', 'organizationId', 'createdAt', 'targets'], 'properties': {'id': {'type': 'string'}, 'source': {'type': 'string'}, 'status': {'type': 'string'}, 'content': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'targets': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'socialAccountId', 'status', 'externalUrl', 'publishedAt', 'lastError'], 'properties': {'id': {'type': 'string'}, 'status': {'type': 'string'}, 'lastError': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'externalUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'publishedAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'socialAccountId': {'type': 'string'}}, 'additionalProperties': False}}, 'createdAt': {'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, 'scheduledAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}}, 'additionalProperties': False}, 'cancelled': {'type': 'number', 'description': 'When cancelling: destinations stopped before they started.'}, 'still_going': {'type': 'array', 'items': {'type': 'string'}, 'description': 'When cancelling: destinations already in flight, which cannot be stopped.'}}, 'additionalProperties': False}
products_delete
Delete a product
Delete a product. Its accounts stay connected and belong to no product afterwards. Refused while it has campaigns. Its knowledge documents and gathered research are deleted with it, so this is refused while it has any unless confirm_discard is true — read the refusal, which says how many would go, before confirming.
파괴적 작업
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['id'], 'properties': {'id': {'type': 'string', 'description': 'The product, from products_list.'}, 'confirm_discard': {'type': 'boolean'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['deleted', 'accountsUnlinked', 'knowledgeDeleted', 'researchDeleted'], 'properties': {'deleted': {'type': 'string'}, 'researchDeleted': {'type': 'number'}, 'accountsUnlinked': {'type': 'number'}, 'knowledgeDeleted': {'type': 'number'}}, 'additionalProperties': False}
products_list
List products
The products your accounts post for — an app, a book, a shop — each with the accounts linked to it and the workspace it is in. An account belongs to at most one product. Use products_save to create one or change which accounts belong to it.
읽기 전용 멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'properties': {}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['products'], 'properties': {'products': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'organizationId', 'name', 'description', 'accounts'], 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'accounts': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'platform', 'handle', 'displayName', 'status', 'refreshTokenExpiresAt', 'organizationId', 'avatarUrl', 'profileUrl', 'scopeCoverage'], 'properties': {'id': {'type': 'string'}, 'handle': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'status': {'type': 'string'}, 'platform': {'type': 'string'}, 'avatarUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'profileUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'displayName': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'scopeCoverage': {'anyOf': [{'type': 'object', 'required': ['granted', 'expected', 'held', 'missing'], 'properties': {'held': {'type': 'array', 'items': {'type': 'string'}}, 'granted': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'missing': {'type': 'array', 'items': {'type': 'string'}}, 'expected': {'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}}, 'additionalProperties': False}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}, 'refreshTokenExpiresAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}}, 'description': {'type': 'string'}, 'organizationId': {'type': 'string'}}, 'additionalProperties': False}}}, 'additionalProperties': False}
products_save
Save a product
Create a product, or change one. Found by id when given, otherwise by name (ignoring case) and created when there is none, so saving the same product twice changes nothing the second time. account_ids is the complete list of accounts that post for it: accounts in another product move here, and accounts in this one that are not listed leave it. Leave it out to keep the accounts as they are. A product holds accounts from one workspace; when you are in several and name no accounts, pass workspace_id (from accounts_list).
멱등성
입력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['name'], 'properties': {'id': {'type': 'string', 'description': 'An existing product to change, from products_list.'}, 'name': {'type': 'string', 'maxLength': 80, 'minLength': 1, 'description': 'The name, or the new name when id is given.'}, 'account_ids': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Every account that posts for it, from accounts_list.'}, 'description': {'type': 'string', 'maxLength': 500, 'description': 'What it is, in a sentence or two.'}, 'workspace_id': {'type': 'string'}}}
출력 스키마
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['product', 'created'], 'properties': {'created': {'type': 'boolean'}, 'product': {'type': 'object', 'required': ['id', 'organizationId', 'name', 'description', 'accounts'], 'properties': {'id': {'type': 'string'}, 'name': {'type': 'string'}, 'accounts': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'platform', 'handle', 'displayName', 'status', 'refreshTokenExpiresAt', 'organizationId', 'avatarUrl', 'profileUrl', 'scopeCoverage'], 'properties': {'id': {'type': 'string'}, 'handle': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'status': {'type': 'string'}, 'platform': {'type': 'string'}, 'avatarUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'profileUrl': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'displayName': {'anyOf': [{'type': 'string'}, {'type': 'null'}]}, 'scopeCoverage': {'anyOf': [{'type': 'object', 'required': ['granted', 'expected', 'held', 'missing'], 'properties': {'held': {'type': 'array', 'items': {'type': 'string'}}, 'granted': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0}, 'missing': {'type': 'array', 'items': {'type': 'string'}}, 'expected': {'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}}, 'additionalProperties': False}, {'type': 'null'}]}, 'organizationId': {'type': 'string'}, 'refreshTokenExpiresAt': {'anyOf': [{'type': 'string', 'format': 'date-time', 'pattern': '^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$'}, {'type': 'null'}]}}, 'additionalProperties': False}}, 'description': {'type': 'string'}, 'organizationId': {'type': 'string'}}, 'additionalProperties': False}}, 'additionalProperties': False}
변경됨
posts_list
2026년 10월 1일 2:51 AM
변경됨
media_upload
2026년 10월 1일 2:51 AM
삭제됨
posts_update
2026년 9월 29일 2:59 AM
삭제됨
posts_schedule
2026년 9월 29일 2:59 AM
삭제됨
posts_performance
2026년 9월 29일 2:59 AM
삭제됨
posts_cancel
2026년 9월 29일 2:59 AM
삭제됨
media_update
2026년 9월 29일 2:59 AM
삭제됨
media_confirm
2026년 9월 29일 2:59 AM
삭제됨
groups_update
2026년 9월 29일 2:59 AM
삭제됨
groups_create
2026년 9월 29일 2:59 AM
삭제됨
accounts_performance
2026년 9월 29일 2:59 AM
변경됨
posts_list
2026년 9월 29일 2:59 AM
추가됨
posts_save
2026년 9월 29일 2:59 AM
추가됨
media_save
2026년 9월 29일 2:59 AM
변경됨
media_list
2026년 9월 29일 2:59 AM
변경됨
media_upload
2026년 9월 29일 2:59 AM
추가됨
groups_save
2026년 9월 29일 2:59 AM
변경됨
groups_list
2026년 9월 29일 2:59 AM
추가됨
products_delete
2026년 9월 29일 2:59 AM
추가됨
products_save
2026년 9월 29일 2:59 AM
추가됨
products_list
2026년 9월 29일 2:59 AM
변경됨
accounts_connect
2026년 9월 29일 2:59 AM
변경됨
accounts_list
2026년 9월 29일 2:59 AM
변경됨
groups_update
2026년 9월 27일 2:50 AM
변경됨
groups_create
2026년 9월 27일 2:50 AM
변경됨
groups_list
2026년 9월 27일 2:50 AM
변경됨
accounts_connect
2026년 9월 27일 2:50 AM
변경됨
posts_performance
2026년 9월 27일 2:50 AM
변경됨
accounts_performance
2026년 9월 27일 2:50 AM
변경됨
accounts_list
2026년 9월 27일 2:50 AM