Data Connectors
Data Connectors in the sidebar of the admin console at app.flexivity.ai is where you connect your own systems, such as Stripe or anything you reach through Zapier, so the AI can look up a customer’s records there.
Only an Admin can connect, change or remove a data connector. A Knowledge Manager or a Read Only user can see the page with every control switched off. See Users.
The AI uses the lookups you enable when it answers Zendesk tickets, Zendesk chat conversations and osTicket tickets (see When the AI looks something up). A tool that changes something, such as a refund, is carried out as its write mode says: prepared for an agent to approve, or made by the AI itself where you choose Execute (see Who carries out a change, and Prepared Changes for Zendesk and osTicket).
How a lookup works
Every lookup is about the customer on the ticket. Flexivity fills in who the customer is (their email address) from your help desk. Nothing the AI writes, and nothing typed in a conversation, can make a tool look up a different customer.
For each tool you decide which fields of the result the AI may see. Each field is either passed or withheld:
- A field you have not listed is withheld.
- Card numbers, government ID numbers and bank account numbers are masked even inside a field you pass.
- Some fields are always withheld, such as Stripe’s card and billing details, and you cannot pass them.
Flexivity keeps little of what it reads. When the AI uses a lookup in a reply, it keeps the values the reply used, so an agent can see them (below); numbers, dates, statuses and ids are kept as they are, a name, an address, an email, a phone number, an ID number or a date of birth never is, and other text has personal details removed first. When a tool that changes something takes its target from a read (below), Flexivity keeps the ids and amounts of the records that read returned on the ticket, and nothing else, so it can check the change. Those are deleted a week after the ticket is solved or closed, and when a ticket is deleted. The test customer you type is never stored.
When the AI looks something up
On a Zendesk or osTicket ticket at the Assist, Reply, Clarify or Resolve level, and in a Zendesk chat conversation, before the AI writes, it can use the lookups you have enabled for the brand when the answer depends on the customer’s own record, such as “Did my refund go through?”. It uses at most a few lookups for one reply, and only ones you enabled.
-
Chat: signed-in customers only. Lookups of a store’s catalog, such as Shopify’s product lookups, are the exception: they look up no one, so they run for anyone. In a chat, the AI looks a customer up only when they are signed in to your chat (through your help center or your own sign-in), and then it uses one email address on their profile. A customer who is not signed in is never looked up: when they ask about their own order or account, the AI says it cannot see their account in this chat and offers a person, and offers signing in if you have turned on Customers can sign in to chat. When their account is the whole question, the chat is handed to a person with a standard message saying so, which you can reword under Brand voice. It never asks them for an email address or an order number to look them up. A lookup that answers slowly makes a chat customer wait for it: on a tool’s page, turn Use in chat off to keep that lookup for tickets only (a Zapier lookup can take ten seconds or more).
-
osTicket. Lookups need Flexivity plugin 2.9.0 or later, and a self-hosted install also needs agent 1.5.0 or later. An older install gets no lookups and replies exactly as before. The customer’s email addresses are read from your osTicket at the time of the lookup and are never stored.
-
Signed-in tickets. Some tools are used only for a signed-in customer. A Zendesk ticket counts as signed in when it was submitted through your help center’s web form by a registered customer (one who has signed in before), which relies on Zendesk’s Verify anonymous requests setting staying on, as Zendesk recommends; an osTicket ticket when it came through the web portal on an install that requires customers to sign in. Other tickets reach only the tools that do not need it.
-
What the customer sees. An answer that states what the record shows, such as “Your refund of $25.00 was issued on 3 October.” Nothing the AI can’t see (a withheld field) is ever stated. The AI never asks the customer for their email address or account details: who they are comes from your help desk. If the lookup finds no record for them, the reply says so and asks for a detail the lookup can use, such as an order number, or hands the ticket to a person. If your system can’t be reached, the reply answers what your knowledge sources cover and says the account can’t be checked right now, or hands over when nothing else is left.
-
What the agent sees. In the Flexivity app on the ticket, Context has a Looked up section listing each lookup, when it ran, what came back (“Found”, “No record for this customer”, “Could not reach the system”) and the values the reply used. A value that is not kept shows as “(not shown)”.
-
Checks. What a reply states from a lookup is checked against the record, as an answer from an article is checked against the article, when answer verification is on.
A lookup through Zapier uses tasks from your Zapier plan (two per lookup in our tests), including the lookups the AI makes on tickets.
Connect Stripe
- In Stripe, create a restricted key (Developers → API keys → Create restricted key). Give it Read on Customers, Charges and Invoices. A secret key (
sk_…) is refused. - In Data Connectors, choose Connect Stripe, paste the key and save.
- If you have more than one help desk, choose which one the connector belongs to.
Flexivity offers five Stripe tools. All of them start Off:
| Tool | What it does | Kind |
|---|---|---|
find_customer | Finds this customer’s Stripe customer record (account status and balance). | Reads |
recent_charges | Lists this customer’s recent charges: amount, status, refunds and dates. | Reads |
get_charge | Looks up one of this customer’s charges by its id (ch_…). | Reads |
recent_invoices | Lists this customer’s recent invoices: number, status, totals and dates. | Reads |
refund_charge | Refunds one of this customer’s charges, in full or in part. | Changes, moves money, cannot be undone |
A charge or invoice that belongs to another customer is never returned: the lookup answers No record was found for this customer.
Flexivity can’t see what a restricted key is allowed to do, so the connector reminds you to keep it read-only. Stripe’s own permissions are a second layer: with Read only on Customers, Charges and Invoices, no refund can be made with the key, whatever is enabled here.
A test key (rk_test_…) reads your Stripe test data. A live key reads real customer records, including in test calls, and the connector shows a warning.
Connect Shopify
The Shopify connector is in beta. Its lookups and changes work, and its screens and steps may change. The connector’s page in the console is marked Beta.
Flexivity can look up a customer’s orders in your Shopify store: their recent orders, and one order in full with its items, shipments and tracking. It can look up your products’ prices and whether they can be bought now. It can also prepare three changes to an order: cancel it, refund items, and change where it ships.
You don’t type in your store’s address or paste a key. Shopify connects a store by installing an app, so:
- In Data Connectors, choose Connect Shopify. Shopify opens Flexivity’s app page.
- Install the app on your store. Shopify asks you to approve what it can access.
- Shopify opens Flexivity inside your Shopify admin. Choose Finish connecting in Flexivity.
- Back in Flexivity, choose the brand this store serves and confirm. Only an administrator of your Flexivity account can do this. The link works once and for 7 days, and opening Flexivity in Shopify again gives you a new one.
Flexivity offers seven Shopify tools. All start Off:
| Tool | What it does |
|---|---|
orders_for_customer | This customer’s most recent orders (up to 10): order number, date, payment and fulfilment status, total and items. |
get_order | One order the customer names, by its order number (#1042) or the confirmation code from their order email: items, each shipment’s status, carrier, tracking number and link, delivery dates, and the city and country it ships to. |
find_products | Your published products matching the words the customer used (up to 10): title, type, brand, whether any version can be bought now, and the lowest and highest price. |
get_product | One product in full: its options (such as size and colour) and, for each version, its price now, its price before any reduction, and whether it can be bought now. |
cancel_order | Cancels one of the customer’s orders that has not shipped. |
refund_items | Refunds items of one of the customer’s orders that have shipped, at the amount Shopify computes. |
update_shipping_address | Changes where one of the customer’s orders that has not shipped will be sent. An agent enters the new address. |
Things to know:
- The customer is matched by email. Flexivity finds the Shopify customer whose email is the ticket requester’s (or the signed-in chat customer’s). If no customer matches, or two do, the lookup finds nothing for them: Flexivity never guesses between customers.
- A customer only ever sees their own orders. An order number that belongs to someone else is “not found”, with nothing about it shown or kept.
- Only the last 60 days of orders are visible. That is Shopify’s default for apps. For an older order, the AI says it was not found among the customer’s recent orders and passes the conversation to a person if they insist.
- What the AI never sees: the customer’s name, email and phone, street address and postcode, notes, tags, order risk and payment details. The shipping city and country are the only part of an address it is given.
- If Shopify has not approved a field Flexivity uses, the connector page shows Shopify has not approved: … and the AI is told the field was withheld.
- Uninstalling the app in Shopify ends Flexivity’s access at once, and the connector shows Needs attention. Reinstalling it reconnects the same connector, with nothing to claim again.
- The product lookups are about your catalog, not the customer. They look up no one, so the AI can use them for anyone, including a chat visitor who has not signed in. They never show how many are in stock, only whether something can be bought now, and prices are in your store’s currency. Product descriptions themselves come from your Shopify store’s Knowledge Source.
- A store connected before the product lookups existed gets them, Off, the next time you open its connector page, like the change tools before them.
- A store connected before the change tools existed gets them, Off, the next time you open its connector page. Shopify asks the store to approve the app’s wider access once, the next time someone opens Flexivity in the Shopify admin.
Shopify changes
Each change goes through the same steps as any other: a procedure step names it, the AI prepares it for this customer’s own order from a lookup on the ticket, every check runs, and it is carried out as its write mode says (see Who carries out a change).
| Change | Refused when | Amount checked by your limits |
|---|---|---|
| Cancel an order | The order has shipped (even partly), or is already cancelled. | What the cancellation refunds under your policy (nothing if the policy refunds nothing). |
| Refund items | An item has not shipped, or more is asked for than can still be refunded. | Shopify’s own figure for those items. |
| Change the shipping address | The order has shipped (even partly), or is cancelled. | None: no money moves. |
- Shopify decides the amount. A refund is the amount Shopify computes for the items named, including their tax and discounts. The AI never names an amount. If Shopify’s figure changes between preparing the change and running it (a discount applied in between, say), nothing runs and the card says so.
- Only items that have shipped are refunded. An order that has not shipped is cancelled instead.
- Shipping is never refunded unless an agent adds it on the card.
- Cancellations and refunds can’t be undone. The card says so, and so does the confirmation when you choose Execute.
- A cancellation can take a moment in Shopify. Until Shopify confirms it, the card reads Sent: Shopify is still cancelling this order, and the customer is not told it is done. Flexivity checks again every few minutes for a day.
- If Shopify refuses a change, the card shows it could not be completed. Shopify’s own message is not kept.
Your store’s policy. On the page of cancel_order and of refund_items, How the store makes this change sets
what Shopify does:
| Tool | Setting | Default |
|---|---|---|
cancel_order | How the cancellation refunds: to the original payment, as store credit, or not at all | To the original payment |
cancel_order | Return the items to stock | Yes |
cancel_order | Shopify also emails the customer | No |
refund_items | Return the refunded items to stock | No (an agent can change it on the card) |
refund_items | Shopify also emails the customer | No |
Each shows whether you set it or it is the default, and Use the default returns it. A change is made with the policy in force when it was prepared, so changing the policy does not change a change already waiting.
A new address is entered by an agent, and never kept. The AI never sees a customer’s street address, so it can’t supply one. When a change of address is prepared, the agent types the new address on the card when approving it. It is sent to Shopify once and is not stored by Flexivity, written to its logs or put in the decision note. Because a person always enters it, an address change can’t be set to Execute; it can be set to Hold or Assist.
Stripe and Shopify refunds on one brand. A brand can have both: a Stripe refund pays back a charge, a Shopify refund pays back items of a store order. They are separate tools with separate limits and policies. Name the one a procedure should use in its steps (the Damaged item refund sample uses Stripe’s, Damaged item refund (store order) uses Shopify’s), and avoid two live procedures that could both refund the same purchase.
Connect another system (custom MCP server)
Any system with an MCP server can be connected. Choose Connect an MCP server, give it a name and its server address (https://…, public addresses only), then choose how it authorises:
- Sign in with the server: you are sent to the server’s own sign-in page and back.
- An API key or token.
- A key in a named header, such as
X-API-Key. - The address itself is the secret, as with a Zapier server URL.
Connecting enables nothing. The connector’s page lists its tools in a table; each tool has its own page. You add one with Add a tool:
- Find the server’s tool, and give your tool a name and a description of what it does.
- Fill in what it should always do. The form is built from the tool’s own inputs: where the server can list the choices (a spreadsheet, a worksheet, a column, a table), choose Show choices and pick one. Some inputs wait for another to be chosen first, and some tools show more fields once you have chosen, with Show the rest of its fields.
- On the input the customer’s email goes in, choose The customer’s email goes here. Flexivity fills that one in from the ticket; the AI never sees or chooses it.
You then land on the new tool’s page, where you say whether it reads or changes something, test it and enable it. You can edit its fixed values there later; saving them turns the tool off until you test and enable it again.
Some server tools can never be added, such as Zapier’s tool for changing its own configuration.
Zapier
Use managed mode. In your server’s settings at mcp.zapier.com, set the mode to Managed and add the actions you want as tools. In agentic mode (Zapier’s default for new servers) the server can add tools from inside a conversation; the connector warns you, and Zapier’s tools for changing the server can never be added.
To connect, generate a token on the server’s Connect tab, then use the address https://mcp.zapier.com/api/v1/connect with An API key or token. The token is shown once; treat it like a password.
Zapier returns some results by position rather than by name: a Google Sheets row as COL$A, COL$B…, a Zapier Tables record as f1, f2…. Flexivity names Sheets columns for you (Email (COL$A)). Zapier doesn’t say what a table’s fields are called, so name them yourself beside each one in What the AI may see; each column’s Field ID is shown in Zapier’s table designer. A field Flexivity can’t read the name of is suggested withhold. When choosing a table’s lookup field, type its Field ID, for example f1.
Each read through Zapier uses tasks from your Zapier plan, two per lookup in our tests. A test call shows how many it used.
Test a tool, then enable it
A read must be test-called before it can be enabled:
- On the tool’s page, enter a test customer’s email, fill in any input the AI would give (each shows the format it expects), and choose Run test call.
- What the AI would receive shows the passed fields and lists every withheld one. On the first call nothing is passed yet. Beside each field, Flexivity suggests pass or withhold, withholding anything that looks personal, such as an email or an address.
- Choose Pass or Withhold for each field in What the AI may see. Each choice saves as you make it, and changing them later keeps an enabled tool on. Test again, then choose Enable. Enabling a tool that passes nothing asks you first.
Use a test customer, not a real one. The address you type is not stored, and it is not shown back.
A tool that changes something can be enabled without a test call. Once enabled, a procedure can propose it, and an agent approves each change on the ticket (see Who carries out a change).
Test as a ticket’s requester
On a read’s page, Test as a ticket’s requester runs the tool exactly as it will run on a ticket: you enter a ticket number and Flexivity reads the ticket’s requester from your help desk, so you never type a customer.
- Only a ticket you marked as a test ticket can be used, so the test can never be used to look up a real customer:
- Zendesk: tag a ticket raised by a test customer
flexivity-test. - osTicket (plugin 2.10.0 or later, and agent 1.6.0 for a self-hosted install): set the ticket’s Flexivity field to Test ticket. Flexivity checks the mark before anything about the requester is read.
- Zendesk: tag a ticket raised by a test customer
- The ticket’s brand must be one the connector is bound to.
- The result shows what the AI would receive, and Customer identified by, which says how the requester was matched. It never shows their email address. If the requester has several addresses, Flexivity tries each in turn and says which one found the record.
A change’s target comes from a read
A tool that changes something, such as a refund, should only ever act on a record the customer was shown in the same conversation. When you add such a tool, choose From a read on the input that names the record (an order, a charge, a loyalty record), then the read it comes from and the field that holds the record’s id.
On a ticket, Flexivity then accepts as the target only a record that read returned to the ticket’s requester, and refuses anything else, even a real record of another customer. For Stripe’s refund_charge this is set up for you: the charge must come from get_charge or recent_charges, and a refund can be at most what is left of that charge, in its currency.
Only an enabled read of the same connector can be a source, and only a field you pass. If the read is switched off, removed, or stops returning that field, the change is switched off too, and its page says why. Enable it again once the read is back.
Who carries out a change
For each brand, a tool that changes something is carried out in one of four ways, its write mode, chosen on the tool’s page. The modes are a ladder, like the levels that decide what the AI may do in a conversation, from the least the AI does to the most:
| Write mode | What happens |
|---|---|
| Manual | A person does it, the conversation is handed over. The tool is not used. |
| Assist (the default) | The AI prepares it and a person approves it. The conversation is handed over. |
| Hold | The AI prepares it and a person approves it. The conversation is paused for the person then resumed by the AI. |
| Execute | The AI executes the change, within its limits, without a person. |
In more detail:
- Manual: the AI hands over with what to do (“cancel order #1004”), and nothing is prepared. The agent makes the change in your system.
- Assist: the change is ready on the ticket, with every check Flexivity ran, and runs only when an agent approves it. The agent can edit it first, or reject it. The customer gets your brand’s hand-over message. See Prepared Changes.
- Hold: as Assist, but the customer stays in the conversation. The AI tells the customer a teammate is confirming their request and waits. When the agent approves, the change runs and the AI tells the customer it is done, in the same conversation, and carries on. If the agent rejects it, or nobody decides within 4 business hours, the conversation is handed to an agent as with Assist, and the change can still be approved on the card.
- Execute: no person approves it. The AI makes the change itself, within the tool’s limits, and tells the customer it is done in the same conversation, once your system confirms it. If the change fails, the customer is told it could not be completed and the conversation is handed to an agent. See Execute for what holds a change back for a person.
Hold and Execute apply only where the AI may resolve conversations (the Resolve level). Elsewhere they work as Assist, because only at Resolve does the AI carry a conversation on after a change.
Each write mode at each level
The level a ticket is handled at is set by your Conversation Handling Rules. Changes are prepared only from a procedure, and procedures run at Assist, Reply, Clarify and Resolve:
| Write mode | Ignore, Label, Gated | Assist | Reply, Clarify | Resolve |
|---|---|---|---|---|
| Manual | Nothing is prepared | The agent sees what to do; the AI does not write to the customer | The AI hands over; the agent sees what to do | The AI hands over; the agent sees what to do |
| Assist | Nothing is prepared | The change is ready on the ticket for the agent to approve; the AI does not write to the customer | The AI hands over; the change is ready to approve | The AI hands over; the change is ready to approve |
| Hold | Nothing is prepared | As Assist | As Assist: the AI hands over | The customer waits while an agent approves; the AI then tells them it is done and carries on |
| Execute | Nothing is prepared | As Assist | As Assist: the AI hands over | The AI makes the change and tells the customer it is done |
Some things lower the mode for one change, whatever is set:
- Execute becomes Hold when the change needs something only a person can enter (a new shipping address), a procedure question was not asked, or the circuit breaker or a pause holds it back.
- Execute becomes Assist when Flexivity can’t reach your system to make the change, or the conversation is already waiting on another change.
- Prepared changes are on Zendesk and osTicket tickets (osTicket needs plugin 2.10.0, and agent 1.6.0 for a self-hosted install). In a chat, and on an older osTicket plugin or agent, the AI hands over with what to do, as with Manual.
A brand with nothing chosen takes its parent brand’s choice. The page also lists the published procedures that may propose the change. A procedure or a handling rule can restrict its own tickets, but never widen them: Never Execute (Execute follows Hold: a person approves every change), Never Hold (Execute and Hold follow Assist: the conversation is always handed over) or Manual (every change follows Manual).
Execute
Only an administrator can choose Execute, and the console asks you to confirm that no person will approve these changes. At the foot of the tool’s page, What has happened to this change shows, for each brand and mode over the last 7, 30 or 90 days, how many changes were prepared, approved unchanged, approved with edits, rejected, done, failed, marked wrong by an agent, and, under Execute, held for a person and whether the customer came back. Open any count to see its tickets.
Before a change runs unattended:
- A change that moves money needs a largest amount per change. Execute is refused until the tool has one, and the limit can’t be removed while any brand runs the tool with Execute. A tool that is not classified counts as moving money.
- A procedure question that was not asked holds the change for a person. If a procedure step asks the customer something (a photo of the damage, say) and the conversation reached the change without asking it, the change waits for an agent’s approval, and the card names the question.
- A conversation already waiting on a change hands the next one to an agent.
- If Flexivity can’t confirm whether the change ran, the conversation is handed to an agent and the customer is never told it is done.
Agents see a change the AI made on the ticket’s card, marked Done: the AI made the change, and can mark it This change was wrong for 30 days. The mark changes nothing in your system; it is counted on the evidence, and only the agent who made it can undo it.
The circuit breaker
The circuit breaker watches each kind of change on each brand. When unattended changes run unusually, it puts a person back in the loop:
| Signal | Default | What happens |
|---|---|---|
| Unattended changes of one kind in an hour | more than 10 | That kind of change on that brand halts: every change waits for an agent’s approval (Hold) until an administrator resumes it |
| … in a day | more than 50 | Halts |
| Total amount in a day | more than 10 × the tool’s largest amount per change | Halts |
| Unattended changes for one customer in 30 days | more than 2 | Only that customer’s changes of that kind wait for an agent; everyone else’s still run. It lifts by itself when the window passes |
Your administrators are emailed when the breaker acts, and the console shows a banner. A halt never lifts by itself, and changing a threshold or the write mode doesn’t lift it: resume it under AI Configuration → Unattended changes, which lists what tripped it and the tickets involved.
Each threshold can be set for your account (on the top-level brand) and for each brand, under Unattended changes. The page shows each value in force and where it came from. A value outside its range is refused.
Flexivity can also pause unattended changes for every account during an incident. While it does, every change waits for an agent’s approval, and AI Configuration says so beside your own Replies to customers stop. Your own stop also stops unattended changes, since it stops the AI replying.
Business hours for Hold
The 4 hours are counted in your Zendesk account’s business hours: its default schedule (the first in Admin Center → Objects and rules → Business rules → Schedules) and its holidays. A hold that starts in the evening or at the weekend still holds, and its 4 hours start when your schedule next opens. Zendesk Enterprise schedules applied to a ticket by a trigger are not followed; the default schedule applies to every ticket, and the card names it. With no schedule, or one Flexivity can’t read (only an admin can list schedules, so the user who installed the app must still be an admin), the hours are counted round the clock, and the card says clock hours.
While the customer waits
- Each message the customer writes reaches the agent on the ticket, and the customer gets a fixed reply: their message was passed on and a teammate is still confirming. The AI does not answer it.
- If the customer withdraws the request (“never mind, I’ll keep it”), the change is withdrawn and never runs, and the customer is told it was cancelled. The AI decides only whether the message withdraws the request; a message that doesn’t is left to the agent.
- An agent’s public reply ends the AI’s part of the conversation, as it always does. Internal notes do not: approving is itself an internal note.
- These messages don’t count toward the conversation’s message limit, and a waiting conversation is never closed for silence.
The customer’s three messages (“a teammate is confirming”, “still confirming”, “cancelled”) are standard messages: change their wording in Brand voice, like the others.
Limits on changes
Every tool that changes something runs under limits Flexivity checks before a change is offered for approval, and again when it runs. The tool’s page lists them, each marked default or set:
- At most 1 per customer per 24 hours (default).
- The requester’s email is known: a ticket with no requester cannot be acted on (default).
An administrator can make them stricter on the tool’s page: a largest amount per change, fewer changes per customer or a longer window, a limit per brand, or a verified requester. The defaults can be tightened but never loosened, and a limit you clear goes back to its default.
Brands
A connector is used only for the brand it is bound to, and that brand’s sub-brands. Choose the Brand on the connector page. An unbound connector is not used anywhere. To keep two Stripe accounts apart, connect each one separately and bind each to its own brand.
Health and changes
The connector page shows Health and access: its state, when it last succeeded, recent errors and the state of its credential.
- Connected: working.
- Needs attention: the server refused the credential (for example the key was revoked). Re-authorise the connector.
Flexivity re-reads every connector’s tools once a day, and when you choose Check for changes now. What happens when the server changed a tool depends on the tool:
- Stripe and Shopify tools that read follow the change on their own: their results pass only the fields you chose, so a new field arrives withheld until you pass it. A result in a new shape is taken the same way.
- Stripe and Shopify tools that change something (a refund, a cancellation) follow a change that only rewords the tool or adds something optional. Anything else, such as an input removed or retyped or a new API version, waits for you.
- Tools on a server you connected yourself (for example Zapier) always wait for you, because such a server can change what its tools return.
A change that waits keeps the tool working exactly as you approved it, and Changes to review shows what changed, with a badge on the connector. You accept or reject it. Fields that are new in an accepted change arrive withheld. Changes taken on their own are listed too, as accepted automatically.
On a server you connected yourself, a result in a different shape from the one you approved (for example a field was added) is refused and shown for review on the tool’s page. The same happens when a Google Sheets column you rely on is renamed. Accepting keeps the tool on and keeps your field choices.
Remove a connector
Remove connector on the connector page deletes its key or sign-in and switches off every tool. It asks you to type the connector’s name first, because a deleted key can’t be recovered. Its history of what was approved stays.