Plug Funnelful into your existing agents.
Funnelful exposes its studio agent as an MCP server over Streamable HTTP. Sessions run with your account's API key, stay out of your Chats in the web app, and are billed to your credits exactly like the web chat. The same key works for the REST API.
One setup for every client. Claude, ChatGPT, Cursor, and any other MCP-capable agent all connect the same way.
- 1In Funnelful, open the MCP/API tab in the side panel and create an API key.
- 2Add an MCP server to your agent (Streamable HTTP):
https://funnelful.ai/api/mcp - 3Send the key in the
x-api-keyheader, or as a Bearer token.
Tools
start_sessionsend_messagewait_for_turnget_messageslist_mediaFastest path: paste this into your agent and it connects itself.
Set up Funnelful for me so I can produce video and image ads from here. 1. Add the Funnelful MCP server: https://funnelful.ai/api/mcp (Streamable HTTP). 2. Authenticate with my API key via the `x-api-key` header: YOUR_API_KEY Once it's connected, let me know — then I can ask you to run ad productions, check on renders, and fetch the finished media.
What your agent can call
funnelful_start_session | Start a new studio chat (one chat = one ad project); returns the sessionId and the chat's link. |
funnelful_send_message | Send a brief to the studio agent and wait for its reply. Long renders return status=running after waitSeconds. |
funnelful_wait_for_turn | Keep waiting on a running turn instead of resending. |
funnelful_get_messages | Latest reply and recent messages, without waiting. |
funnelful_list_media | Stills, video takes, songs, and final cuts made in the chat, with download links. |
funnelful_list_sessions | Your studio chats, newest first. |
funnelful_stop_turn | Stop a running turn; nothing new starts. |
funnelful_list_models | Model playground: the models you can generate with directly, their options and list prices. |
funnelful_quote | The list price of a generate request, without starting or billing anything. |
funnelful_generate | Generate with one model directly (no studio agent); image URLs are fetched server-side. |
funnelful_get_generation | A generation by id, with a download link once it succeeded. |
- Renders take minutes. send_message holds the turn open; when it outlives waitSeconds you get status=running, so poll with wait_for_turn and never resend. A chat answers one message at a time.
- API keys are created and revoked in the studio's MCP/API tab. Each key is shown once.
- Every generation bills the account's credits exactly as the web chat does.
Or call it over HTTP
The same studio agent and models as plain HTTP + JSON at https://funnelful.ai/api/v1, for backends and scripts that don't speak MCP. Same API keys, same credits, same list prices.
- Authenticate with your API key as
Authorization: Bearer ffk_…orx-api-key: ffk_…. Keys come from the studio's MCP/API tab. - Errors are JSON,
{ error: { code, message } }: 400 invalid_request, 401 unauthorized, 402 insufficient_credits, 404 not_found, 409 conflict (a turn is already running), 503 unavailable. - Full reference: openapi.json (OpenAPI 3.1).
Models: generate directly
# List the models, their options and from-prices
curl https://funnelful.ai/api/v1/models -H "Authorization: Bearer $FUNNELFUL_API_KEY"
# Price a request first (nothing is started or billed)
curl https://funnelful.ai/api/v1/quote -H "Authorization: Bearer $FUNNELFUL_API_KEY" \
-H "content-type: application/json" \
-d '{"request":{"model":"gpt-image-2.5","prompt":"a cozy kitchen, morning light","aspectRatio":"9:16"}}'
# Generate: 202 with the generation (status queued or running)
curl https://funnelful.ai/api/v1/generations -H "Authorization: Bearer $FUNNELFUL_API_KEY" \
-H "content-type: application/json" \
-d '{"request":{"model":"gpt-image-2.5","prompt":"a cozy kitchen, morning light","aspectRatio":"9:16"}}'
# Poll: wait (up to 60 s) holds the request until it succeeds or fails; url is the download link
curl "https://funnelful.ai/api/v1/generations/gen:<id>?wait=60" -H "Authorization: Bearer $FUNNELFUL_API_KEY"Reference images take asset: ids from POST /uploads (a file, or a public https url the server downloads) or gen: ids of earlier images.
Agent: run an ad production
# Start a session (one session = one ad project)
curl https://funnelful.ai/api/v1/sessions -X POST -H "x-api-key: $FUNNELFUL_API_KEY"
# Send the brief and stream the turn as server-sent events
curl -N https://funnelful.ai/api/v1/sessions/<id>/messages -H "x-api-key: $FUNNELFUL_API_KEY" \
-H "content-type: application/json" \
-d '{"message":"A 20 s UGC ad for our matcha powder, 9:16"}'
# The agent asked a question? Answer it with the next message
curl -N https://funnelful.ai/api/v1/sessions/<id>/messages -H "x-api-key: $FUNNELFUL_API_KEY" \
-H "content-type: application/json" -d '{"message":"Go with the second script"}'
# Renders finish after the turn: follow the session until the media is ready
curl -N https://funnelful.ai/api/v1/sessions/<id>/events -H "x-api-key: $FUNNELFUL_API_KEY"turn.started | The turn began. |
message.delta | Assistant text as it streams. |
tool.started / tool.completed | The agent called a tool, and it finished (ok, plus a short summary). |
generation.created / generation.updated | A still, clip or song started, or changed status (url once succeeded). |
turn.completed | The turn ended, with the full reply. Last event of the message stream. |
turn.failed / turn.stopped | The turn failed (with the reason) or was stopped. |
- A session answers one message at a time (409 while a turn runs). When the agent asks you something, the turn completes with the question as its reply: answer with the next message.
- Prefer one JSON answer? Send
"stream": falseand"wait"(up to 300 s); a turn that outlives it answersstatus: "running". Never resend: follow/events. /eventsstays open, replays the running turn and emitsgeneration.updatedas renders finish. Reconnect withLast-Event-IDto resume. Media and links:GET /sessions/<id>/generations.