The builder exposes an MCP (Model Context Protocol) server, so an AI agent —
Claude, Cursor, ChatGPT/Codex, or your own client — can drive it: start a build
from a reference image, iterate on the popup, and turn the result into a
campaign. This article covers where to mint a credential, what the endpoint
speaks, and where its limits are.
Create an API key
Go to Settings → API keys. The panel opens with:
Connect the OptiMonk MCP server to AI agents like Claude or Cursor.
next to a Documentation link that points at the in-app article/docs/authentication.
Type a Key name (placeholder: "e.g. Claude connection") — the name is
required; leaving it empty gives you "Give the key a name."Press New key.
The Key created panel appears with the full secret and the warning "You
can only see the full key now — copy and store it safely. It can't be shown
again." Use Copy.
Afterwards the list shows only the key's 14-character prefix followed by dots,
its "last used" date and its creation date. Secrets are stored as a SHA-256
hash, never in plaintext, so there is no way to recover one — mint a new key
instead. Revoke kills a key immediately: "Any agent using this key loses
access immediately. This can't be undone."
Keys look like omk_live_<43 base64url chars>. The same page also lists
Connected apps — the OAuth equivalent, for clients that can run a browser
consent flow: "Apps you approved with Connect. They act on this account until
you disconnect them."
The endpoint
POST https://<your-host>/mcp
Authorization: Bearer omk_live_…
Transport is streamable HTTP and stateless — the server creates a fresh
session per request, so GET /mcp and DELETE /mcp both answer 405 method not allowed (stateless). The server identifies itself as optimonk-popup-builderversion 1.0.0.
Auth details worth coding against:
The bearer must start with
omk_. Anomk_at_…prefix is treated as an OAuth
access token, anything else as an API key.A missing, malformed, revoked or expired credential gets
401with aWWW-Authenticateheader. When OAuth is enabled that challenge carries aresource_metadatapointer (RFC 9728), which is what lets a capable client
start the consent flow itself instead of asking you for a key.Requests from a browser origin outside the allow-list get
403.Request bodies are capped at 1 MB; larger ones get
413.If both the API-key and OAuth doors are switched off server-side,
/mcpanswers404 mcp disabled.
Both credential kinds carry the same four scopes: build:read, build:write,campaign:read, campaign:write. A key created from the settings UI gets the
full set. Call whoami first — it returns the account id, the credential label,
the scopes and canPublish, which disambiguates "object not found" from
"credential pointed at the wrong account".
What the tools can do
26 tools are exposed. Grouped by job:
Identity:
whoami.Build:
build_popup,get_build_status,watch_build,upload_reference_image,get_popup_html,get_popup_preview.Iterate:
edit_popup,patch_popup,restore_revision.Design conversation:
start_design_thread,send_design_message,get_design_thread,get_concept_board,select_variant.Campaign:
list_campaigns,get_campaign,create_campaign,set_campaign_name,get_campaign_settings,set_campaign_settings,publish_campaign.Coupons:
get_coupon,set_coupon.Jobs:
get_job,watch_job.
build_popup takes a publicly fetchable PNG/JPG/WEBP plus the target store
hostname and returns a runId. Builds are asynchronous: prefer watch_build(it waits and emits progress notifications) over a polling loop, and useget_build_status for a single read or from a client that cannot hold a request
open. interrupted is not a terminal status — the run resumes; treating it
as a failure is the most common mistake on this surface.
create_campaign makes a DRAFT campaign and needs a designer-session-backed
build: start_design_thread creates one, a standalone build_popup run does
not. publish_campaign publishes to OptiMonk and activates the campaign.
What it is not for
It is not the analytics or subscriber API. There is no tool for reports,
leads or submits — the tool list above is the whole surface.It cannot configure ESP/CRM integrations. No tool connects Klaviyo,
Mailchimp or a webhook; that is UI-only, in the campaign hub.It cannot manage the account. No user, domain, billing or API-key
administration; key and connected-app endpoints are cookie-authenticated on
purpose, so a credential can never enumerate or revoke its siblings.Do not branch on HTTP status alone. MCP tool refusals — including scope
errors and exhausted budgets — come back asisError: truewith prose incontent, inside a JSON-RPC HTTP 200 response. They do not use the REST typed
error envelope or the rate-limit headers.Do not retry a timed-out build blindly. Pass
idempotencyKeytobuild_popup(the REST equivalent is anIdempotency-Keyheader, honoured
for 24 hours per account); a retry with the same key returns the first run
instead of paying for a second generation.
Scripting instead of an agent?
The same credentials work against a REST surface described by an OpenAPI 3.1
document. Both GET /.well-known/openapi.json and GET /llms.txt are readable
without a credential. REST errors are typed (type + code + request_id;
branch on those, not on message), rate-limited responses carryX-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a
budget refusal is a 429 with Retry-After.