Shopify Integration Guide

Tajo connects Shopify to Brevo in two places. The Tajo Shopify app turns Shopify webhooks into Brevo writes as they arrive. Sync rules, which an agent builds and a person approves, move records into Brevo on a schedule. This page covers both, then the Shopify tools Tajo serves over MCP.

Prerequisites

Before starting the integration, ensure you have:

  • Shopify store on any plan (Basic, Shopify, Advanced, or Plus)
  • Tajo account (Tajo is in early access)
  • Brevo account, the destination for the sync
  • Admin access to your Shopify store

Step 1: Connect Your Shopify Store

Tajo is in early access. The Shopify app is not listed in the Shopify App Store, and there is no self-serve install link. Contact the team to get set up. Once your Tajo workspace is ready:

  1. In Tajo, open Connections.
  2. Enter your store’s myshopify.com domain and choose Connect Shopify. Shopify shows the scopes Tajo requests and returns you to Tajo when you approve them.
  3. Check what each scope is for, and what Tajo writes back to Shopify, in Shopify permissions explained.

Step 2: What the Tajo Shopify App Sends to Brevo

The app verifies each Shopify webhook, stores it, queues it and processes it straight away. Customer and product topics wait about four seconds first. There is no batch window. A failed job is retried with backoff.

Webhook topics

The Tajo Shopify app subscribes to these Shopify webhook topics:

Webhook topicsPurpose
customers/create, customers/update, customers/deleteKeep Brevo contacts current
orders/create, orders/updated, orders/fulfilled, orders/cancelledOrder events and order metrics for Brevo
orders/paid, refunds/createAward and deduct loyalty points
checkouts/create, checkouts/updateAbandoned checkout recovery in Brevo
products/create, products/update, products/deleteKeep the product catalog in Brevo current
inventory_levels/updateKeep product stock in Brevo current
collections/create, collections/update, collections/deleteKeep collections current
companies/*, company_contacts/*, company_locations/* (create, update, delete)B2B company sync
app/uninstalled, app/scopes_update, app_subscriptions/updateApp lifecycle

Shopify’s mandatory privacy webhooks (customer data request, customer redact, shop redact) are also handled. The app does not subscribe to carts/*. Abandoned carts come from the checkouts/* topics.

What lands in Brevo:

Shopify eventIn Brevo
Customer created or updatedThe contact is created or updated with name, email and marketing consent. On paid plans the app adds tags, order count, amount spent and last order.
Customer deletedThe contact is unsubscribed, not deleted
Order created, updated, paid, fulfilled or cancelledThe order through Brevo’s orders API, and the events order_paid, order_completed and order_cancelled
Refund createdThe event order_refunded. If you run a Brevo loyalty program through Tajo, points are deducted in proportion.
Order paid, with a Brevo loyalty programPoints awarded at your points-per-dollar rate
Checkout created or updated, with an email and itemsThe events cart_updated and cart_abandoned. Your Brevo automation decides when to send.
Product or collection created, updated or deletedBrevo’s product catalog and categories
Inventory level updatedThe product’s stock in Brevo’s catalog. When a variant goes from 0 to above 0, each shopper who asked to be notified gets a back_in_stock event, once per restock.

The app does not add a “Notify me” button to your theme. A back-in-stock request has to come from your storefront, for example from a button you add.

Existing data

On install, the app imports your existing customers as Brevo contacts. A full historical sync is started from the app’s sync page. On paid plans it also imports products, collections, companies and orders.

Step 3: Build a Sync Rule with the Agent

A sync rule is a declarative definition of one sync: a source resource, a Brevo action, a field map and a filter. You do not write it by hand. You describe it, an agent builds it, and a person approves it.

  1. In Tajo, open Agents and ask the Brevo Integration Architect for the sync in plain language. For example: “Send Shopify customers who accepted email marketing to Brevo as contacts.”
  2. The agent inspects the Shopify connector. Its sample returns field names and types, never customer values.
  3. It proposes a rule with a field map and a filter, then validates the field map against Brevo’s action and dry-runs the draft. Neither step reads customer records.
  4. It saves the rule as a draft. You can also start from a template under Connections > Syncs and mappings > New sync from template.
  5. Request publish approval runs a preview against your store. It reads at most 10 records, writes nothing to Brevo and does not move the cursor. It records counts only: records pulled, eligible, mapped and rejected by the filter, plus mapping errors. If the preview fails, no approval is created.
  6. A person approves the request on the Approvals page, with a written rationale. The approval is bound to a SHA-256 digest of the rule and expires after 30 minutes. The rule page then shows Publish approved version.

Editing a published rule returns it to draft. It goes back through preview and approval before it runs again.

A real rule

This is the Shopify customers -> Brevo contacts template as Tajo defines it:

sourceSlug: "shopify",
sourceResource: "customers",
destinationSlug: "brevo",
destinationAction: "upsert_contact",
fieldMap: [
{ source: "email", destination: "email", transform: "toLowerCase" },
{ source: "first_name", destination: "attributes.FIRSTNAME" },
{ source: "last_name", destination: "attributes.LASTNAME" },
{ source: "phone", destination: "attributes.PHONE" },
{ source: "total_spent", destination: "attributes.TOTAL_SPENT", transform: "toNumber" },
{ source: "orders_count", destination: "attributes.ORDERS_COUNT", transform: "toNumber" },
{ source: "tajo_email_marketing_consent", destination: "attributes.OPT_IN", transform: "toBoolean" },
{ source: "tags", destination: "attributes.SHOPIFY_TAGS" },
{ source: "id", destination: "attributes.SHOPIFY_ID", transform: "toString" },
{ source: "created_at", destination: "attributes.SHOPIFY_CREATED_AT" },
{ source: "updated_at", destination: "attributes.SHOPIFY_UPDATED_AT" },
],
filterExpression:
"($json.tajo_email_marketing_consent === true) && ($json.tajo_email_suppressed === false)",

The filter is the consent check. Tajo derives both values from Shopify’s email_marketing_consent.state, or the older accepts_marketing flag. A rule that writes contacts to Brevo cannot be published without it. The other Shopify template, Shopify orders → Brevo orders, records orders in Brevo for buyers who accepted marketing at checkout.

When a rule runs

  • Contact sync rules run every 15 minutes by default. Each run starts from the rule’s cursor.
  • An active rule’s page has a Test run (1 batch) button.
  • An active, published Shopify orders → Brevo orders rule also runs every 15 minutes. Its first scheduled run starts a few minutes before that moment and sends no older orders. Each later run sends the orders updated since the previous one.
  • Past orders reach Brevo only when you run the rule yourself: with Test run (1 batch), or by asking the Sync Operator agent to run it.
  • An orders rule runs on schedule only with the template’s buyer marketing opt-in filter. A rule whose filter was edited runs only when you start it.
  • After five consecutive failed runs, the rule pauses itself and its page shows the last error. Fix the cause, then publish again.

Each run is listed in the rule’s run history with records read, written and failed, and its duration.

What the Shopify Connector Reads and Writes

Sync rules only write to the destination, here Brevo. They never write to Shopify.

The Tajo Shopify app requests 12 scopes and makes a short list of writes to Shopify, such as consent opt-outs and loyalty tags. Shopify permissions explained lists every scope and every write, with what triggers it.

Agents and MCP hosts reach the store through the Shopify connector:

ReadsWrites
Shop details, customers (list and search), orders, products, customer metafields, inventory levels, bulk export statusCustomer metafields and customer tags, and starting a bulk export. Each write is staged as a proposal and runs only after it is approved.

The connector also declares an inventory adjustment. It needs the write_inventory scope, which the Tajo Shopify app does not request.

Step 4: Use the Shopify Tools over MCP

Tajo serves the Shopify connector as an MCP server at https://alto.tajo.io/mcp/connectors/shopify. Add it to Claude Code:

Terminal window
claude mcp add --transport http tajo-shopify https://alto.tajo.io/mcp/connectors/shopify

The host discovers Tajo’s OAuth server and opens the Tajo sign-in. Access is limited to early-access accounts. The server exposes 12 tools:

ToolWhat it does
preview_tajo_shopify_appInteractive preview of the Tajo Shopify app, rendered as MCP UI
get_shopThe shop’s details
search_customersSearch customers with Shopify query syntax, such as tag:tajo-vip or total_spent:>100
list_customersList customers, paginated
list_ordersList orders, paginated
list_productsList products with variants, images and inventory
get_customer_metafieldsRead a customer’s metafields
get_inventory_levelsRead a variant’s inventory across locations
poll_bulk_exportCheck a bulk export and get its download link when it completes
calculate_rewards_profileCalculate a customer’s tier, points and reward balance from synced commerce data
shopify_proposeStage one Shopify write as a proposal. Nothing is sent.
shopify_applyRun an approved proposal

Troubleshooting

Next Steps

Request early access

Enter your first name and business email address. We will email you a link to confirm your request for Tajo access.

AI Assistant

Hi! Ask me anything about the docs.

This page as Markdown: shopify.md

Loading Markdown…