Changelog
Changes to the VYG API, MCP server and documentation, newest first.
2026-10-01
Email tools for AI assistants. Brands with email enabled can run the email channel from an assistant connected
to https://agents-mcp.vyg.app/mcp: sending domains, templates with variables, test sends to your own inbox,
abandoned checkout and other automated emails with an Email or Resend step, segments, scheduled broadcasts and
deliverability monitoring. Saved templates are live immediately once they pass the template checks. See
Email tools.
Business address and catalog sync for email tools. email_brand_address_get and email_brand_address_set read
and save the postal address that every marketing email shows. Going live needs one. You can also set it in VYG under
Settings → Email. email_catalog_sync_request queues a full product catalog sync. Template saves from an assistant
now follow the same rules as saves in VYG: an edit that would overwrite a newer save is refused. See
Email tools.
2026-09-28
Collection error format changed. Update integrations that read error responses. Errors from
POST /cdp/events and POST /cdp/ingest on https://cdp.vyg.app are now {"error": {"code", "message"}},
the same format and codes as api.vyg.app, instead of {"error": "<code>", "error_description": "..."}.
Success responses are unchanged.
batch_too_large,scope_bindingandpayload_too_largearebad_request. The size limit keeps its413status, and a scope-binding rejection still lists the events inrejected.forbiddenisinsufficient_scope,internal_errorisinternal, andservice_unavailableisunavailable.service_unavailable_partialis a503unavailablethat carriesacceptedandfailednext toerror. Resend only the events listed infailed.- Error responses with the envelope carry an
X-Request-Idheader, which browsers can send and read. - Some responses use a
{"message": "..."}body:404for a method or path the host does not serve,429for the rate limit, and500or503when a request cannot be completed. Check the status, and readerror.codeonly when the body has anerrorobject.
The web pixel, the Shopify pixel and Shopify's compliance webhooks read only the status, so they need no
change. Server integrations that read the error string on /cdp/events need to read error.code. Every old
code and its replacement is in the migration guide.
See Collect errors.
One list envelope, snake_case fields and cursor paging (breaking). A clean break with no aliases: old field names, old query parameters and old tool arguments are not accepted and not returned. Every change is listed in the migration guide.
- One list envelope. Every list returns
{ data, next_cursor }.next_cursorisnullon the last page and on lists that return everything at once. The other envelopes are gone:{ data, nextCursor },{ list, totalSize, offset, pageSize, scope, nextCursor },{ list, scope },{ eventTypes, scope },{ properties, catalogVersion },{ insights, totalCount },{ workflows, totalCount }and the conversation search and insight conversation envelopes. Segment members keepgenerationand the customer field catalog hascatalog_versionbeside the page. - Cursors instead of offsets. Commerce orders and subscriptions, customers at risk, conversation
insights and the conversations for an insight take
cursor(the previous page'snext_cursor). Theoffsetparameter is removed, andtotalSize,pageSize,offset,scope,totalCount,totalFoundandlimitare no longer returned on lists. - Unknown list parameters are refused. Every list refuses a parameter or tool argument it does not
take, such as
offset, with400bad_requestinstead of ignoring it.GET /v1/segmentspages withcursortoo. limitover 100 is a400. Commerce orders, subscriptions and products and customers at risk answer400bad_requestfor alimitover 100; they used to reduce it to 100.- Single records are bare. Get a conversation or contact; get, create and update a provider or an
event definition; and create, rotate and revoke a key return the record itself instead of
{ "data": { ... } }. - snake_case everywhere. Every query parameter, path parameter, body field, MCP tool argument and
response key is snake_case. Path parameters are
{provider_id}and{definition_id}, the/v1/keysparameter iskey_class, andlist_customerssorts bytotal_spend,orders_count,created_at,last_order_atorlast_event_at. - MCP tool arguments.
read_shopify,mutate_shopifyandquery_shopifytakeapi_version(wasapiVersion);learn_shopify_api,search_shopify_docsandvalidate_shopify_graphqltakeconversation_id(wasconversationId); andvalidate_shopify_graphqltakescodeblocks[].artifact_id(wasartifactId). - Opaque values keep their inner keys: segment
definition, event typeschema, providersettings, event definitionpayload_schemaandidentifier_mappings, campaign rules and goals, checkoutline_itemsanddiscount_codes, and the Shopify and Klaviyo payloads. The error envelope is unchanged.
Renamed fields by resource (old → new):
| Resource | Renamed fields |
|---|---|
| Conversations and messages | createdAt → created_at, updatedAt → updated_at, lastEngagedAt → last_engaged_at, lastReceivedAt → last_received_at, awaitingReply → awaiting_reply, cartValue → cart_value, cartCurrency → cart_currency, checkoutState → checkout_state, lastMessage → last_message, sentAt → sent_at, scheduledFor → scheduled_for |
| Contacts | givenName → given_name, familyName → family_name, acceptsSmsMarketing → accepts_sms_marketing, createdAt → created_at, updatedAt → updated_at |
| Conversation search | conversationId → conversation_id, textContent → text_content |
get_conversation_details | createdAt → created_at, scheduledFor → scheduled_for, sentAt → sent_at, goalStateChanges → goal_state_changes, totalPrice → total_price, lineItems → line_items, discountCodes → discount_codes |
| Providers | lookupId → lookup_id, sourceTemplateKey → source_template_key, isEnabled → is_enabled, apiKey → api_key, webhookSecret → webhook_secret, webhookUrl → webhook_url |
| Event definitions | providerId → provider_id, payloadSchema → payload_schema, identifierMappings → identifier_mappings, schemaVersion → schema_version, sourceTemplateKey → source_template_key, isEnabled → is_enabled, createdAt → created_at, updatedAt → updated_at |
| API keys | keyClass → key_class, firstKey → first_key, keyPrefix → key_prefix, brandId → brand_id, createdAt → created_at, lastUsedAt → last_used_at, expiresAt → expires_at, revokedAt → revoked_at |
| Customers | createdAt → created_at, ordersCount → orders_count, totalSpend → total_spend, totalRefunded → total_refunded, lastOrderAt → last_order_at, coverageFrom → coverage_from, events30d → events_30d, sessions30d → sessions_30d, productViews30d → product_views_30d, lastEventAt → last_event_at, mergedCustomerIds → merged_customer_ids, firstOrderAt → first_order_at |
| Customer activity | eventKey → event_key, occurredAt → occurred_at, eventType → event_type, sourceSystem → source_system, entityKind → entity_kind, entityKey → entity_key, productKey → product_key, pagePath → page_path, pageTitle → page_title, referrerHost → referrer_host, utmSource → utm_source, utmMedium → utm_medium, utmCampaign → utm_campaign, sessionId → session_id |
| Customer orders and subscriptions | orderKey → order_key, subscriptionKey → subscription_key, sourceSystem → source_system, financialStatus → financial_status, fulfillmentStatus → fulfillment_status, billingInterval → billing_interval, nextBillingAt → next_billing_at, lineId → line_id, productKey → product_key, variantKey → variant_key, unitPrice → unit_price |
| Customer fields | catalogVersion → catalog_version, readOnlyReason → read_only_reason |
| Segments | currentVersionId → current_version_id, createdBy → created_by, evaluationStatus → evaluation_status, memberCount → member_count, evaluatedAt → evaluated_at, lastRunAt → last_run_at, currentVersionEvaluated → current_version_evaluated, schemaVersion → schema_version, segmentId → segment_id, estimatedAt → estimated_at |
| Segment members and history | customerId → customer_id, lrContactId → lr_contact_id, joinedAt → joined_at, currentCustomerId → current_customer_id, changedAt → changed_at |
| Products | images[].altText → images[].alt_text |
Brand (get_brand) | companyWebsite → company_website, supportEmail → support_email, supportPhone → support_phone, escalationEmail → escalation_email, tosUrl → tos_url, privacyPolicyUrl → privacy_policy_url, faqPageUrl → faq_page_url, reEngagePeriod → re_engage_period, createdAt → created_at, planName → plan_name, planPrice → plan_price, usageChargePercentage → usage_charge_percentage, billingEmail → billing_email, paymentProvider → payment_provider, isEnabled → is_enabled, lookupId → lookup_id |
| Conversation insights | updatedAt → updated_at, conversationId → conversation_id, createdAt → created_at, checkoutState → checkout_state, messagePreview → message_preview |
| Performance stats and campaign comparison | currentValue → current_value, previousValue → previous_value, comparisonChart → comparison_chart, dateRange → date_range, compareFrom → compare_from, compareTo → compare_to, brandId → brand_id, isPaused → is_paused, workflows → campaigns (comparison) |
| Campaigns | isPaused → is_paused, startsAt → starts_at, endsAt → ends_at, delayMinutes → delay_minutes, delayType → delay_type, weekDays → week_days, specificTime → specific_time, nodeId → node_id, externalId → external_id, agentReply → agent_reply, replyWithMessage → reply_with_message, contactSupport → contact_support, supportEmail → support_email, flowMessages → flow_messages, knowledgeBase → knowledge_base |
search_klaviyo_docs | resultCount → result_count, operationId → operation_id, docUrl → doc_url, guideTopics → guide_topics, endpointFamilies → endpoint_families |
Commerce orders and subscriptions, customers at risk, integrations and event types kept their item fields; only their list envelope changed. Message variants, discounts, campaign writes, campaign building options and the LTV, RFM and top-products reports are unchanged.
2026-09-27
Routes, tools and permissions renamed. Update existing integrations.
- Campaign reads moved to
/v1/campaigns:GET /v1/campaigns,GET /v1/campaigns/{campaign_id}andGET /v1/campaigns/compare(wasPOST /v1/workflows/compare). - Performance stats are
GET /v1/stats(wasPOST /v1/dashboard/stats). - Conversation search is
GET /v1/conversations/search(wasGET /v1/search/conversations), and customer search takesqueryinstead ofq. - The customer field catalog is
GET /v1/customers/fields(wasGET /v1/traits). - The RFM tool is
get_rfm_tiers(wasget_customer_segments). - Parameters these routes and tools take are snake_case:
campaign_id,campaign_ids,include_historical,compare_from,compare_to,day_limit,insight_idandconversation_id. - The old tool names from 2026-09-26 (
list_workflows,customers_getand the rest) no longer work. - Scopes:
workflows:readiscampaigns:readanddashboard:readisstats:read. Existing sign-ins keep their access. Campaign building options acceptcampaigns:readorcampaigns:write.
The old paths answer 404. Every change is listed in the
migration guide.
API fixes.
- A temporary failure in a LiveRecover read, such as performance stats or conversation search,
now returns
500internalor503unavailableinstead of400bad_request. GET /v1/commerce/orders/{id}andget_orderaccept theidthatlist_ordersreturns, as well as the Shopify order id.GET /v1/providersandlist_providersreturn an empty list, not404, for a brand with no providers.POST /v1/providersno longer returns avyg_live_key thatapi.vyg.apprefused. Called with a sign-in token that haskeys:manage, it returns avyg_ba_apiKeywithproviders:readandproviders:write; called with an API key or any other token,apiKeyisnull.- The dashboard no longer shows a
vyg_live_value as a provider's API key. Connecting the integration, adding a provider and regenerating a provider's credentials issue avyg_ba_key withproviders:readandproviders:write, the keyPOST /v1/providersreturns. Regenerating issues the new key before it revokes the old one. A user who is not a brand admin gets no key: adding a provider creates it without one, and regenerating replaces only the webhook secret and keeps the current key. - The per-brand provider limit answers
409with the new codelimit_reachedinstead of429rate_limited. See Errors. - The OpenAPI document types every
limitandoffsetas an integer, and documents the fields of the brand, conversation insights, conversation search, performance stats, campaign and customer insights responses.
Documentation moved to docs.vyg.ai. Browse by task: Get started, Connect an AI assistant, REST API, Data collection, Custom Integration and this changelog. Every old page URL redirects to its new page.
- The REST reference now covers every
/v1route, grouped by area, and marks the operations that need a sign-in. - The tool catalog lists all available MCP tools.
- The OpenAPI document at
https://api.vyg.app/v1/openapi.jsonnow has a summary, description and tag for each operation, plusx-mcp-tool,x-scopesandx-oauth-only.
2026-09-26
One API at api.vyg.app. The REST API and the MCP server now run on one host:
- REST:
https://api.vyg.app/v1 - MCP:
https://api.vyg.app/mcp
It replaces:
| Retired | Replacement |
|---|---|
mcp.vyg.app | https://api.vyg.app/mcp |
cdp-mcp.vyg.app | https://api.vyg.app/mcp |
cdp.vyg.app read routes | https://api.vyg.app/v1 |
brand-api.vyg.app | https://api.vyg.app/v1. brand-api.vyg.app is being retired. |
cdp.vyg.app stays up for event collection only (/cdp/ingest, /cdp/events, /cdp/vyg.js).
One MCP server. The conversation, campaign and analytics tools and the customer-data tools are on the same server. What a connection can use depends on its scopes, not on which server it connects to.
Renamed MCP tools. Tools now follow a verb_noun pattern, and campaign tools use "campaign" instead of
"workflow", for example list_workflows is now list_campaigns and customers_get is now get_customer.
The old names stopped working on 2026-09-27. The full list is in the
migration guide.
Scopes. Sign-in tokens carry granular scopes such as customers:read and campaigns:write. mcp:tools,
mcp:read and mcp:write are still accepted when signing in and expand to granular scopes. API keys carry a
scope list chosen when they are created. See Scopes.
Saved segments on api.vyg.app. List, create, change, archive and estimate segments, and read their
members and history, over /v1/segments and the matching MCP tools. See the
Segments reference.
See the migration guide for what to change.