FoodPerfect Docs

Tool reference

The server exposes 51 tools and no MCP resources or prompts. Your client discovers them with tools/list, which returns each tool's full JSON Schema. This page is the human-readable version.

Legend

  • Read: free, changes nothing, no extra headers.
  • Write: creates or changes something. From your own code, an Idempotency-Key header makes retries safe (how).
  • Approval: returns requires_approval first (how it works).
  • Cost is charged from the account's dollar balance at the plan's rate (prices). Failed generations are refunded.

Inputs are strict: unknown fields are rejected with invalid_input. Parameters marked optional can be left out.

#Account and brand

#ping

Read · free. Returns server health, version and environment. Call it first to check the connection. No inputs.

#get_account

Read · free. Returns the key owner's account: plan, planId, subscriptionStatus, totalBalanceUsd, and the balance split in micro-dollars (planBalanceMicros, packBalanceMicros, totalBalanceMicros; 1,000,000 = $1). No inputs.

#get_brand_dna

Read · free. Returns the Brand DNA built during onboarding: tone of voice, content pillars, goals and post types. No inputs.

#update_brand_dna

Write · free. Updates parts of the Brand DNA.

Parameter Type
updates object Required. At least one of goals (string), pillars (string), toneOfVoice (string), postTypes (array).
userComments string Optional. Notes on why it changed.

#run_brand_analysis

Write · free. Scrapes your Instagram account and website, then builds the Brand DNA (pillars, goals, tone of voice, post types, reel types, example captions) with Gemini. Free (no balance charge), limited to 5 runs per hour. Takes roughly 1 to 4 minutes: the call waits up to about 4 minutes; if it returns completed=false, poll get_brand_analysis_status until completed is true (status "draft", stage "done") or status is "error". Replaces the existing Brand DNA.

Parameter Type
instagramUsername string Required. The account to scrape.
siteUrls array Optional. Up to 3 website URLs.

#get_brand_analysis_status

Read · free. Progress of the latest run_brand_analysis: status (scraping, analyzing, draft, error), analysisStage (scraping_posts, analyzing_batches, synthesizing, done, failed), scraped post count and any scraping errors. completed=true means the Brand DNA is ready for get_brand_dna.

No inputs.

#regenerate_brand_dna

Write · free. Revises the existing Brand DNA with Gemini, applying the comments saved on the DNA (section comments and per-type userComments) and, when platform is given, extending the strategy to that platform (seeds a monthly plan if none exists). Requires an existing Brand DNA (run run_brand_analysis first). Free (no balance charge), limited to 10 per hour. Takes about 30 to 90 seconds.

Parameter Type
platform "instagram" | "tiktok" | "facebook" | "linkedin" Optional. Extends the strategy to a new platform.

#Photos, promos and menus

#photo_prompt

Read · free. Previews what generate_photo would send, without generating or charging: returns { prompt, styleImageUrl, styleName, width, height, model }.

Parameter Type
dishName string Required.
styleId 1–8 Required. See the styles below.
description string Optional. The dish in your words.
mode "similar" | "exactCopy" Optional, default "similar".
perspective 1–3 Optional. 1 top view, 2 angle, 3 side.
ratio "1:1" | "2:3" | "3:2" | "4:5" | "9:16" Optional, default "1:1".
globalInstructions string Optional extra direction.
hasUploadedImage boolean Optional.

Photo styles: 1 On the go · 2 Humans · 3 Color burst · 4 Crystal light · 5 Straight blue · 6 Bright casual · 7 Pop art · 8 Velvet core. See them on the homepage.

#generate_photo

Write · 1 image · returns the finished photo (usually under a minute). Makes one AI food photo in a FoodPerfect style with the same GPT Image pipeline as the app, saves it to your library and returns { generation } with its storageUrl. Several dishes are composed into one photo.

Parameter Type
dishes array Required, 1–6 of { name, image?, description? }. image is a URL of your own photo of the dish (strongly recommended); without one, description is what the dish is made from.
styleId 1–8 Required.
mode "similar" | "exactCopy" Optional, default "similar": a new shot from the style's photo session. "exactCopy" puts your dish into the style's exact shot.
ratio "1:1" | "2:3" | "3:2" | "4:5" | "9:16" Optional, default "1:1".
perspective 1–3 Optional. 1 top view, 2 angle, 3 side.
globalInstructions string Optional.

Images are downloaded before you're charged, so a bad image link costs nothing.

#generate_promo

Write · 1 design · returns the finished promo. Designs a promotional graphic.

Parameter Type
heading string Required. The headline.
subheading string Optional.
dishes array Optional. { name, description?, price? } each.
promoMaterials array Optional. { type: "image" | "text", content, description? }, e.g. a logo URL or a line of copy.
ratio "1:1" | "4:5" | "9:16" Optional, default "1:1".
styleReference object Optional. { imageReference?, textDescription? }.

#generate_menu

Write · 1 design · returns the finished menu. Designs a menu board.

Parameter Type
categories string Required, e.g. "Starters, Mains, Desserts".
dishesData string Required. Dishes with prices and descriptions, as text.
menuCustomization string Optional design notes.
ratio "1:1" | "9:16" Optional, default "1:1".
visualMaterials array Optional. { type: "image" | "text", content, description?, filename? }.
styleReference object Optional. { imageReference?, textDescription? }.

#Images

#edit_image

Write · 1 image · edits an existing image with a text instruction (GPT Image 2.5, medium quality) and saves the result as a NEW library item; the original is untouched. Source: generationId (a library item) or assetId or imageUrl. Optional referenceImages (URLs or asset ids, up to 15) are extra visuals, e.g. a dish to insert.

Parameter Type
prompt string Required. Text description of what to edit.
source object Required. One of generationId, assetId, or imageUrl.
referenceImages array Optional. URLs or asset ids, up to 15.

#remove_background

Write · 1 image · removes the background from an image (transparent PNG) and saves it as a NEW library item; the original is untouched. Source: generationId (a library item) or assetId or imageUrl.

Parameter Type
source object Required. One of generationId, assetId, or imageUrl.

#upscale_image

Write · free · upscales an image 2x (Real-ESRGAN) and saves it as a NEW library item; the original is untouched. Source: generationId (a library item) or assetId or imageUrl. No charge, but it needs an active plan or the trial (payment_required otherwise) and is limited to 100 upscales per account per UTC day (rate_limited after that; shared with the app).

Parameter Type
source object Required. One of generationId, assetId, or imageUrl.

#upload_asset

Write · free · downloads an image from a public URL (PNG, JPEG, WebP or GIF, size-capped) into the brand asset library, where the app and generation tools can use it as a reference.

Parameter Type
imageUrl string Required. Public URL of the image.
category "brand" | "inspiration" | "upload" Optional, default "upload".

#Video and reels

#list_reel_presets

Read · free. Lists the VideoBeast reel presets (the live reel studio): id, name, description and every field an agent fills (text, lists, pictures) with exact character/item limits and an example shape. Use with create_reel; the examples come from a sample restaurant, copy their shape and length, not their content.

No inputs.

#create_reel

Write · free. Creates a draft VideoBeast reel project from a preset (from list_reel_presets), the user's pictures and optional text, exactly as the reel editor saves it. Returns the projectId plus missing fields still needed before render_reel. Fill text with generate_reel_script, add clips with animate_reel_shot and music with generate_reel_music, then render_reel.

Parameter Type
presetId string Required. A preset id from list_reel_presets.
pictures array Required. Picture ids or URLs.
text object Optional. Text fields for the preset.

#generate_reel_script

Write · 1 post · writes the on-screen copy, caption and hashtags of a VideoBeast reel project with the same scriptwriter as the reels autopilot (Gemini, brand voice, humanizer rules, template character limits) and saves them into the project. Create the project first with create_reel; the pictures already in it are what the copy is written about. Refunded on failure.

Parameter Type
projectId string Required. An existing reel project from create_reel.

#prepare_reel_art

Write · images, plus 1 animated shot for splash and mascot flows · makes a promo poster's flexible art: the fields of kind "art" in list_reel_presets (falling fruit, a scene, a coloured liquid splash, the owner's mascot). Object flows draw the subject on white and cut it out; splash flows animate a splash in the given colour with a transparent background; mascot flows redraw the owner's character on white, animate it in a loop and cut it out. Mascot posters require their mascot before render_reel (it appears in missing). Returns { jobId, jobType: "reelArt", status: "queued" }; poll get_job_status with jobType: "reelArt" until status is completed (urls) or failed (refunded). With projectId the result is put into the reel project.

Parameter Type
presetId string Required. A promo poster preset with the field.
field string Required. The art field key, e.g. art_mascot.
input string Required. Mascot flows: the mascot image (asset id, upload id, generation id or https URL). Others: a few words (the subject or the colour).
projectId string Optional. A reel project from create_reel to put the result into.

#animate_reel_shot

Write · 1 animated shot · turns one photo slot of a VideoBeast reel project into a ~5 s animated shot (Grok Imagine 1.5 Lite, 480p) and stores it asynchronously. Optional motion (how it moves), sound (what we hear, e.g. "oil sizzling on a hot grill"; never music or speech) and asmr (close-up ASMR sound design for a process shot). Shots are silent unless sound or asmr is given; then the rendered reel plays the shot's sound, under the reel's music when it has a music bed. Returns { jobId, status: "pending" }. Poll with get_job_status using jobType: "reelClip" and the returned jobId. When it completes the clip replaces the photo in the project; the project has awaitingClips=true until every pending shot settles, and render_reel must wait for that. Failed or timed-out shots are refunded and the photo stays.

Parameter Type
projectId string Required.
slotIndex integer Required. Which photo slot to animate (0-based).

#generate_reel_music

Write · free · generates an original instrumental brand track (ACE-Step) and, when projectId is given, bakes it into that VideoBeast reel project (replacing any music). Synchronous: no job to poll.

Parameter Type
projectId string Optional. A reel project from create_reel.

#render_reel

Write · free · async. Renders a reel project to video. Returns { jobId, status: "pending" }. Poll with jobType: "reel". Cannot start while awaitingClips is true (animated shots are still rendering).

Parameter Type
projectId string Required.

#generate_video_from_image

Write · 1 video clip · async. Animates a still into a short clip that keeps the image's proportions, with no music or sound. A food video (default) is a dish photo with one camera move (Grok Imagine 1.5 Lite, 480p). A promo card animation brings a finished promo card to life (steam, glistening food, bouncing badges, a light sweep) and starts and ends on the exact card, so its text and prices stay intact (MiniMax H3, first and last frame). Returns { taskUUID, status: "pending" }. Poll with get_job_status using jobType: "video" and the taskUUID as jobId.

Parameter Type
imageUrl string Required. A FoodPerfect image URL or another allowed host.
videoType "food" | "promo" Optional, default "food".
motionDirection 1 | 2 | 3 Required for food videos, ignored for promo cards. 1 zoom out, 2 orbit around the dish, 3 camera rises to a top view.
duration 5 | 8 Optional seconds, default 5.
width, height integer Optional, default 1280×720.

Write · free (limit 10 per hour). Finds trending TikTok videos for a query and imports the top ones as reel assets to use as an opening hook.

Parameter Type
query string Required.
platform "tiktok" Optional, default "tiktok".
rank "top" | "fresh" Optional, default "top".
maxCandidates 1–10 Optional, default 6.
hookSeconds 1–15 Optional, default 4.

Warning

Imported clips belong to their creators. Check you have the rights before publishing anything built on them. See the Acceptable Use Policy.

#generate_reel_storyboard (legacy)

Write · free (limit 60 per day). Prefer list_reel_presets + create_reel. Writes a reel storyboard from a brief using your assets where they fit.

Parameter Type
prompt string Required, at least 5 characters.
availableAssets array Optional. { assetId, name, type: "image" | "video", durationSeconds? }.
restaurantName, cuisine string Optional.

#resolve_reel_generators (legacy)

Write · 1 reel segment per AI clip block. Prefer create_reel + animate_reel_shot. Fills the empty generator blocks of one reel project. Trending-hook blocks resolve immediately; AI clip blocks start video jobs you poll with get_job_status (jobType: "video"). Refunds per block on failure.

Parameter Type
projectId string Required. An existing reel project from the old Reel Studio.

#list_reel_templates (legacy)

Read · free. Prefer list_reel_presets. Lists the reel templates available to everyone. No inputs.

#Posts

#generate_post_example

Read · with generateImage: 1 image · previews a strategy post type: generates an example caption (free) and optionally an example image (charged as one image). Mirrors the app Strategy example preview; nothing is saved to Brand DNA or any post.

Parameter Type
postType string Required. A post type from your Brand DNA.
generateImage boolean Optional, default false. When true, generates an example image (charged).

#generate_scheduled_post_content

Write · with generateImage: 1 post · generates caption text for an existing scheduled post and optionally attaches an existing generation image. With generateImage=true it produces the full post like the app (caption + image, charged as one post; failures are refunded).

Parameter Type
postId string Required.
generateCaption boolean Optional, default true. Set false to only attach an image.
generateImage boolean Optional, default false. When true, generates a new image.
sourceImageId string Optional. A generation id to attach instead of generating.
contentInstructions, globalInstructions string Optional.

#Inbox

#list_inbox

Read · free. Lists inbox items (customer comments and DMs) newest activity first, with optional platform, status, type and needsHuman filters. Paginated: pass nextCursor back as cursor.

Parameter Type
platform "instagram" | "tiktok" | "facebook" | "linkedin" Optional filter.
status "needs_reply" | "draft_ready" | "done" Optional filter.
type "comment" | "dm" Optional filter.
needsHuman boolean Optional. Filter to items the autopilot couldn't handle.
cursor string Optional, from the previous page.
limit 1–50 Optional page size, default 20.

#get_inbox_item

Read · free. Returns one inbox item (classification, draft, autopilot decision, last reply) with its full message thread oldest first, plus which reply options are available right now (DM 24 h window, human-agent tag, private reply).

Parameter Type
itemId string Required.

#get_inbox_settings

Read · free. Returns inboxEnabled (the inbox on/off switch, default true; while off nothing new is collected, replies and sync are blocked, autopilot is off, and stored messages are deleted 30 days after it was switched off) and the inbox autopilot switch, which channels (comments, DMs) and topics autopilot may answer, and the "your rules" knowledge the AI may state as fact. aiDisclosure (default true) says whether autopilot replies end with a short "replied by our AI assistant" notice. Autopilot never auto-sends on LinkedIn: LinkedIn items are draft-only.

No inputs.

#draft_reply

Write · free · drafts (or regenerates) an AI reply for an inbox item in the brand voice, using the "your rules" knowledge. Saves it as the item draft and returns it with the classification. Drafting is free and nothing is sent, but once a draft exists the send_reply for it is charged (edited or not). Rate limited (30/min).

Parameter Type
itemId string Required.

#send_reply

Write · 1 reply (if AI draft) · Approval-gated (if AI draft) · sends a reply to a customer comment or DM from the connected social account. Charged at the reply price when an AI draft was generated for this reply (from draft_reply or the draft the inbox prepared), whether or not you edited it; a reply you write entirely yourself, with no AI draft for it, is free (chargedMicros 0). Refunded if the platform rejects it. Enforces the 24 h DM window (human-agent tag between 24 h and 7 days), the 7-day private-reply window and no double replies. If an AI draft exists, approval is required: the first call returns requires_approval with an approvalToken; repeat the same call with that token to send.

Parameter Type
itemId string Required.
content string Required. The reply text.
isPrivate boolean Optional. For DMs only; posts are always public.
approvalToken string Send on the second call to confirm (if AI draft).

#set_inbox_status

Write · free. Marks an inbox item done (dismissed without a reply) or back to needs_reply.

Parameter Type
itemId string Required.
status "done" | "needs_reply" Required.

#sync_inbox

Write · free · pulls recent DMs and comments for every connected account (Instagram, Facebook, TikTok, LinkedIn) into the inbox. Rate limited to one run per minute. Returns accounts synced, items imported and per-platform warnings.

No inputs.

#update_inbox_settings

Write · free (inbox off) / Approval-gated (autopilot on) · updates inbox settings; only the fields you pass change. inboxEnabled (default true; setting false stops collecting messages, blocks sync, drafts and replies, forces autopilot off, and stored messages are deleted 30 days later, so it requires approval; turning it back on is immediate), autopilotEnabled, aiDisclosure (default true: autopilot replies end with a short "replied by our AI assistant" notice), channels {comments, dms}, autoSendTopics (hours, location, menu_pricing, reservations, delivery_catering, compliment, general) and knowledge (hours, location, reservations, menu, allergens, delivery, rules, signOff; max 2000 chars each). Turning autopilot ON requires approval: the first call returns requires_approval with an approvalToken; repeat the same call with that token to confirm. Turning autopilot OFF applies immediately. Autopilot never auto-sends on LinkedIn (LinkedIn items always stay drafts for you to approve).

Parameter Type
inboxEnabled boolean Optional. Requires approval to set false.
autopilotEnabled boolean Optional. Requires approval to set true.
aiDisclosure boolean Optional.
channels object Optional. { comments, dms } booleans.
autoSendTopics object Optional. Topic keys as booleans.
knowledge object Optional. Knowledge keys as strings.

#prefill_inbox_knowledge

Write · free · suggests the inbox knowledge (hours, location, reservations, menu, allergens, delivery, rules, signOff) from the brand's scraped website and profile, like the app's "Fill from my website" button. Only fields the sources actually state are returned. Saves nothing: review the suggestions, then save them with update_inbox_settings. Rate limited to 5 per minute.

No inputs.

#moderate_comment

Write · free (hide/unhide) / Approval-gated (delete) · hides, unhides or deletes a customer comment on the platform. Hide/unhide: Instagram, Facebook, TikTok; delete: all platforms. Delete is permanent and approval-gated: the first call returns requires_approval with an approvalToken; repeat the same call with that token to confirm. Hide and unhide run immediately.

Parameter Type
itemId string Required. The inbox item id.
action "hide" | "unhide" | "delete" Required.
approvalToken string Send on the second call to confirm (if delete).

#Planning and publishing

#generate_publish_schedule

Write · free. Creates planned posts exactly like the app: for each platform switched on in your publishing settings with a working connection (Instagram, TikTok, Facebook, LinkedIn), weighted by the post-type mix in your Brand DNA, in your timezone, from tomorrow on. Weeks that already have posts are skipped, so running it again doesn't duplicate anything.

Parameter Type
weeksAhead 1–4 Optional, default 4.

#list_scheduled_posts

Read · free. Lists scheduled posts.

Parameter Type
from, to ISO 8601 datetime Optional date range.
platform "instagram" | "tiktok" | "facebook" | "linkedin" Optional.
status planned | text_generated | image_generated | approved | posted | failed Optional.

#publish_post_now

Write · Approval · free. Publishes up to 20 existing scheduled posts right away, each on the platform it's scheduled for, following the app's rules:

  • The account's posting method must be Direct (Settings → Posting method). In Draft mode the call is refused.
  • Each post needs its caption and its image or video. Posts already publishing or posted are skipped with a reason.
  • A post being published is locked, so it can't go out twice. A saved Zernio draft is published instead of creating a new post.
Parameter Type
postIds string[] Required, 1–20 ids.
approvalToken string Send on the second call to confirm.

#schedule_reel_post

Write · Approval · free. Schedules a rendered reel for Instagram.

Parameter Type
projectId string Required.
caption string Required.
scheduledAt ISO 8601 datetime Required.
approvalToken string Send on the second call to confirm.

Read · free. Returns { authUrl, nextStep }, a secure link to connect a social account. A person has to open it and log in; the agent can't do that part. When they say they're done, call finalize_connection.

Parameter Type
platform "instagram" | "tiktok" | "facebook" | "linkedin" Required.
loginMethod "facebook_login" Optional, Instagram only: connect through a Facebook Page.

#finalize_connection

Write · free. Finishes connecting an account after the person has logged in through get_connect_link, and returns the connected username. If they haven't finished yet it returns not_found; ask them to complete the login and try again. Safe to call twice.

Parameter Type
platform "instagram" | "tiktok" | "facebook" | "linkedin" Required.

#Library

#list_generations

Read · free. Your generated images and videos, newest first.

Parameter Type
type photo | promo | menu | video Optional filter.
limit 1–50 Optional page size.
cursor string Optional, from the previous page.

#get_generation

Read · free. One generation by id.

Parameter Type
generationId string Required.

#list_assets

Read · free. Your Brand Assets library plus uploaded assets and fonts, newest first. Each item has a source (brandAssets, userAssets or userFonts).

Parameter Type
type image | video | audio | font Optional filter.

#delete_generation

Write · Approval · free. Deletes a generated image or video and its files.

Parameter Type
generationId string Required.
approvalToken string Send on the second call to confirm.

#delete_asset

Write · Approval · free. Deletes an uploaded asset or font and its files.

Parameter Type
assetId string Required.
approvalToken string Send on the second call to confirm.

#Jobs and approvals

#get_job_status

Read · free. The current state of an async job. Returns { job: { status, … } }. See Async jobs.

Parameter Type
jobId string Required. taskUUID from video jobs, jobId from reel renders.
jobType "video" | "reel" Required.

#confirm_action

Write. Confirms a pending approval with its token, without resending the original arguments.

Parameter Type
approvalToken string Required.