Integrations & connectors
Integrations & connectors
Telenow agents don't just talk — they act. An agent can append a row to your Google Sheet, create a CRM lead, send a WhatsApp confirmation, raise a Razorpay payment link, or book a Calendly slot, all mid-call. It can also fetch a caller's record before it starts speaking so it can open with "Hi Sarah, I see you're on the Premium plan."
This page is the complete guide to connecting those tools yourself — no developer, no Telenow support ticket. You connect a vendor account once under Workplace → Integrations, then add its actions to any agent as one-click tools.
The big idea: connect once, swap anytime. Credentials live in a workspace connection vault (encrypted). Agents reference the connection and a capability (e.g.
whatsapp.send) — never the credentials, and never a specific vendor. So you can move from one WhatsApp provider to another, or from HubSpot to Salesforce, by repointing the tool — the agent doesn't change, and the model's tool schema stays identical.
Related reading: Tools & function calling for the full tool spec · Building agents for the Tools step · WhatsApp for messaging specifics · Automation platforms for Zapier/Make/n8n · Integration connectors API to do all of this from your own server.
How it fits together
There are three layers, and you only ever touch the first one:
| Layer | What it is | Where you manage it |
|---|---|---|
| Connection | Your org's credentialed instance of a provider (e.g. "Acme Razorpay"). Secrets are AES-GCM encrypted at rest. | Workplace → Integrations → Connected |
| Provider | A catalog entry (Razorpay, HubSpot, …) describing how to authenticate and what actions it offers. | Workplace → Integrations → Available (read-only catalog) |
| Capability | A canonical action like whatsapp.send or crm.create_lead. Every provider that implements it uses the same parameter schema, so vendors are interchangeable. | Bound to an agent in the builder's Tools step |
One connection serves every agent in the workspace. One agent tool points at one connection + capability.
Step 1 — Connect a provider
- Go to Workplace → Integrations in the sidebar.
- Under Available, providers are grouped by category — Messaging, CRM, Calendars & scheduling, Support & ticketing, Commerce & payments, Spreadsheets & data, Forms, Other. Each card shows a short blurb, the actions it offers, and how many connections you already have.
- Click Connect (or Add another if you've connected this provider before).
- A form appears, built from the provider's own field spec:
- Label — a friendly name (e.g. "Sales Razorpay"). You'll pick connections by label later, so make it memorable when you have several.
- Credential fields — paste the API key / token. Secret fields are masked as
••••••••the moment they're saved and never shown again. - Connection settings — non-secret values some providers need (a Freshdesk domain, a Plivo sender number, a Salesforce instance URL).
- Click Connect. For API-key and built-in providers, Telenow runs a quick verification immediately, so the row lands with a truthful status.
Only owners and admins can add, edit, test, or remove connections; any member can see them (the agent builder needs the list).
Or connect it from your own server
Everything on this page has an API behind it, authenticated with an API key rather than a dashboard session:
curl -X POST https://api.telenow.ai/api/v1/integrations/connections \
-H "X-API-Key: your_key" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"providerId":"shopify",
"credentials":{"api_token":"shpat_xxxxxxxxxxxx"},
"settings":{"store_domain":"acme.myshopify.com"}}'
That is the path to use if you are shipping an installable app — a Shopify app, a marketplace listing — or provisioning workspaces from your own system. Your installer already holds the merchant's credentials when its own OAuth finishes; there is no reason to then send them here to paste a token by hand.
GET /api/v1/integrations/providers returns each connector's field spec, so you can build the form from the catalog instead of hard-coding field names.
The three auth types
The catalog flags each provider with one of three auth kinds:
| Auth kind | What you do | Examples |
|---|---|---|
| API key | Paste a key/token (and any settings). Telenow stores it encrypted. | Razorpay, Stripe, Freshdesk, Zendesk, HubSpot, Intercom, GoHighLevel, Microsoft Dynamics 365, Airtable, JotForm, Typeform, Tally, Calendly, Cal.com, AiSensy, GupShup, Plivo & Meta WhatsApp |
| Host + credentials | Host, port, database, user, password and a TLS mode. Tested on save. | PostgreSQL, MySQL, SQL Server, MongoDB |
| OAuth | Click Connect with …, approve on the provider's consent screen, and tokens land automatically. | Google Sheets, Google Calendar, Zoho CRM, Salesforce |
| App registration | Paste your own app's tenant/client ID and secret; Telenow mints and refreshes the short-lived token for you. | Microsoft Dynamics 365 |
| Built-in | No external account — pick something you've already set up in Telenow. | WhatsApp (built-in) — pick a paired number |
Some API-key providers actually use HTTP Basic auth under the hood (Razorpay, Plivo, Freshdesk, Zendesk) — you still just paste two values (a key/ID and a secret), and Telenow synthesizes the Basic base64(id:secret) header for you.
Connecting an OAuth provider (consent flow)
OAuth providers don't take a pasted key — you grant access on the vendor's site:
- Fill any required settings (e.g. Salesforce's Instance URL), then click Connect with <provider>.
- You're sent to the provider's sign-in / consent screen. Approve the requested scopes.
- The provider redirects back to Telenow, which exchanges the code for tokens, encrypts them, and marks the connection active. A toast confirms the result.
A few details worth knowing:
- From Workplace → Integrations, consent opens in the same window and you return to the Integrations page with a status flag.
- From inside the agent builder (Add integration slide-over), consent opens in a new tab so your unsaved agent form survives — approve there, then come back; the new connection's actions appear automatically.
- Tokens auto-refresh. When an access token is within ~60 seconds of expiry, Telenow silently refreshes it using the stored refresh token before dispatching the call — you don't re-authorize routinely. If a refresh ever fails, the connection is parked in an error state with the reason, and you click Reconnect.
- An OAuth connection that hasn't completed sign-in shows Disconnected until the callback lands.
Admin one-time setup for OAuth providers. OAuth uses Telenow's registered app for each vendor, configured by the platform via environment variables (e.g.
GOOGLE_OAUTH_CLIENT_ID,SALESFORCE_OAUTH_CLIENT_ID). If an OAuth provider doesn't appear or sign-in fails, the platform operator hasn't configured that app yet — see Troubleshooting.
Test, edit, remove
On the Connected tab each connection has:
- Test — re-runs the provider's verification request and surfaces the vendor's own error message if it fails. The status chip updates (Active / Needs attention / Disconnected).
- Edit — change the label, settings, or rotate a key. Leave a masked secret untouched to keep the stored value; only type a new value to replace it.
- Remove — deletes the connection. You can't remove a connection while an agent still references it (as a tool or a pre-call lookup) — Telenow blocks the deletion and names the agents so you can detach it first.
The connector catalog
These ship as catalog rows, so the list grows without app updates. Categories shown are the ones used to group the Available tab.
Messaging (WhatsApp)
Five providers all implement the same whatsapp.send capability with identical parameters (to, message), so you can switch WhatsApp vendors without touching your agents. Full setup for each is in WhatsApp.
| Provider | Auth | Notes |
|---|---|---|
| WhatsApp (built-in) | Built-in | Sends through a number already paired to your workspace (no external account). Pick the paired session in the form. Pair one first under Communicate → WhatsApp. |
| Plivo WhatsApp | API key (Basic) | Your own Plivo WhatsApp Business sender. Set the WhatsApp sender (E.164). |
| WhatsApp Cloud API (Meta) | API key | Meta's official Cloud API with your own WABA. Set the Phone number ID from Business Manager. |
| AiSensy | API key | Template campaigns — the message fills the campaign's first template parameter. Set the API campaign name. |
| GupShup | API key | Popular Indian BSP. Set the source number (digits) and app name. |
Free-form text only reaches a contact inside an open 24-hour session window; business-initiated messages may need an approved template (provider-dependent). See WhatsApp.
CRM
| Provider | Auth | Actions |
|---|---|---|
| HubSpot | API key (private app token) | Search, get, create and update contacts; list a contact's deals, get and update a deal; list a contact's companies, get and update a company; list a contact's open tasks, create a task; add a note; log a call onto the timeline. |
| Salesforce | OAuth | Search, get, create and update contacts; get and update leads (create too — requires last name + company); get and update accounts; list an account's opportunities and get one; get a case; look up the staff member a record belongs to; create tasks and notes; read and update your own custom objects. Uses your My Domain instance URL. |
| Intercom | API key (access token) | Create a contact (crm.create_contact), look up by phone (crm.lookup_contact). |
| Zoho CRM | OAuth | Search, get, create and update contacts; list a contact's deals; create tasks and notes; log a call in the Calls module (create a lead too). Connect once with Zoho (India data centre). |
| GoHighLevel | API key (Private Integration Token) | The full sub-account surface: search / get / create / update a contact, add tags, list and manage opportunities, list and create tasks, add notes, and the whole appointment lifecycle — list, check availability, book, get, reschedule, cancel. |
| Microsoft Dynamics 365 | API key (Entra app registration; a token is minted for you) | Search / get / create / update a contact, log a phone call onto the timeline (crm.log_phone_call), add a note, create a task. |
Lookups return a trimmed result (a few relevant fields) to save latency and tokens on a live call. For HubSpot/Intercom lookups, searching by the national number without the country code is usually the most reliable match.
Capability names are shared across CRMs on purpose. Get a contact is crm.get_contact whether the connection behind it is HubSpot, Salesforce, Zoho, GoHighLevel or Dynamics, and every provider implementing a capability takes the same required arguments. That is what lets you repoint a tool at a different CRM without rebuilding the agent. Two consequences worth knowing: HubSpot deals and Salesforce opportunities are the same capability (crm.get_opportunity) under each vendor's own name; and Log call activity is crm.log_phone_call, which is a single-record agent tool and deliberately distinct from crm.log_call, the batch campaign write-back destination.
Not every CRM implements every capability, because not every CRM has the concept. Salesforce lists opportunities by account, not by contact, because a Salesforce contact has no opportunities child relationship — get the account ID from the contact first. Zoho contacts have no company text field (it is a lookup to an Accounts record), so Create contact there takes no company. Dynamics has no such field either and offers job_title instead. A tool moved to a CRM that lacks a field keeps working; the argument is simply unused.
GoHighLevel needs two things: a Private Integration Token (Settings → Private Integrations) scoped for contacts, opportunities and calendars, and your sub-account Location ID. An agency-level token is refused by every endpoint. Booking requires a contact_id, so point the agent at Look up a contact (or Create a CRM contact, which matches an existing record rather than duplicating it) before Book an appointment; each booking tool picks its own calendar.
Zoho CRM rows target the India data centre (zohoapis.in), matching the connector's accounts.zoho.in sign-in — refresh tokens are data-centre bound, so a token minted elsewhere will not work. Two things to know before you rely on it: contact search needs the search scope, which older Zoho connections were never asked for (if Look up contact returns 401 while everything else works, reconnect to add it); and Log a phone call asks for a duration as hh:mm, which Zoho requires for a call that has already happened.
Salesforce updates run as a single composite/batch request that patches and then re-reads the record, because a bare Salesforce PATCH returns no body and the agent would have nothing to confirm back to the caller. Read hasErrors before believing an update worked. Contact search uses SOSL over the phone index, so it matches a number however it is punctuated in your org.
Dynamics 365 authenticates as an unlicensed application user rather than as a person, so it survives staff changes and consumes no seat. In your own Entra tenant: register an app, add a client secret, then create an application user bound to that Application ID with a custom security role in the Power Platform admin centre. Paste the tenant ID, client ID, secret and environment URL. Test connection runs WhoAmI, which proves the whole chain — a valid token with no application user behind it fails there, which is the step most first-time setups miss. Contact search is an exact phone match, so store numbers in E.164 or as plain digits.
Calendars & scheduling
| Provider | Auth | Actions |
|---|---|---|
| Google Calendar | OAuth | Book an event (calendar.book) — provide start/end as ISO-8601 with a timezone offset. |
| Calendly | API key (PAT) | Create a single-use booking link (calendar.booking_link). The event type is chosen per tool from your active events. |
| Cal.com | API key (cal_live_…) | The full booking lifecycle: read live free slots (calendar.check_availability), book (calendar.book_appointment), read one back (calendar.get_appointment), move it (calendar.reschedule_appointment), cancel it (calendar.cancel_appointment), list a caller's upcoming bookings by email (calendar.list_contact_appointments), and mint a single-use booking link (calendar.booking_link). The event type is chosen per tool from a live dropdown. |
Cal.com needs an API key from Settings → Developer → API keys (leave the expiry blank — an expired key fails with a 401 that reads like a revoked one). Set the Cal.com account email and pick the timezone the business works in, in full IANA form (Asia/Kolkata, Europe/London) — an abbreviation like IST or EST is accepted and then quietly ignores daylight saving, so every time the agent reads out is an hour wrong. Pass a slot from Check appointment availability into Book an appointment exactly as it came back, offset and all; restating it as UTC books the wrong hour. A reschedule returns a new booking UID and cancels the old one, so use the new UID for anything else on that call. Cal.com cannot look a caller up by phone number — List a caller's appointments needs the email they booked with.
Spreadsheets & data
| Provider | Auth | Actions |
|---|---|---|
| Google Sheets | OAuth | Append a row (sheets.append), find rows (sheets.find_row) and update a row (sheets.update_row). The spreadsheet + tab are chosen per tool — the tab from a live dropdown of the document's sheets — and the columns are discovered live (see Per-tool binding). Find looks a caller up by any value (phone matching ignores formatting) and returns each match with its row_number; update changes only the cells you pass on that row — pair the two to read a booking and change its status mid-call. On multi-tab documents, find/update/list also accept an optional sheet argument so one tool can work across tabs of the same spreadsheet. sheets.update_rows writes MANY rows in one API call — Google meters Sheets writes per user per minute, so flushing a batch beats one write per result. sheets.list_rows is the bulk reader — it pages through the sheet in order (offset + limit, returning has_more/next_offset) and reaches arbitrarily deep, where find_row deliberately stops at 20 matches within the first 1000 rows. Use find to look ONE caller up mid-call; use list to import a whole contact list. |
| Airtable | API key (PAT) | Add a record (record.create). The base + table are chosen per tool; fields are discovered from the table schema. |
Databases
| Provider | Auth | Actions |
|---|---|---|
| Database — PostgreSQL, MySQL, SQL Server, MongoDB | Host + credentials | Two planes. In bulk: fill a campaign from a SELECT you write (db.query), update the rows it dialled (db.update), or append a row per call (db.append). Mid-call: look a record up (db.find), create one (db.create), or change one (db.modify). Tables and columns are read off the connection, so you pick rather than type. A mid-call lookup returns only the columns you tick — a production table carries plenty an agent should never read aloud. See Connecting your database and Database tools for agents. |
All four engines appear under one Database entry in the pickers — click it to choose yours. The connection is tested when you save it, so a green row really did connect; a wrong password or an unallowlisted IP is reported there and then, in your database's own words.
Forms
| Provider | Auth | Actions |
|---|---|---|
| JotForm | API key | Submit a form response (form.submit) — questions are discovered from the form. |
| Typeform | API key (PAT) | Look up responses (form.lookup_responses). Read-only — the Typeform API can't submit responses. |
| Tally | API key | Look up recent submissions (form.lookup_submissions). Read-only. |
Commerce & payments
| Provider | Auth | Actions |
|---|---|---|
| Razorpay | API key (Basic) | Create a payment link (payment.link) in INR. Amount is in paise — ₹500 = 50000. Returns a short URL the agent can read out or send over WhatsApp. |
| Stripe | API key (secret or restricted key) | Create a payment link (payment.link) in any currency your account presents — a Checkout Session good for 24 hours and payable once. Then check it was paid (payment.status), refund it (payment.refund), and look a customer up by email (customer.lookup) to read their open invoices (invoice.lookup) and subscriptions (subscription.lookup). Set the thank-you page URL per tool; Stripe requires somewhere to send the payer afterwards. |
Stripe: prefer a restricted key (rk_live_…) over the account secret key — Write on Checkout Sessions, Read on Customers, Payment Intents, Invoices and Subscriptions, Read on Balance, and Write on Charges only if the agent should be able to refund. Type the amount as a normal number (999 for $999, 20.45 for $20.45); the conversion to cents is done for you from the currency's own exponent, so never multiply by 100 yourself. Refund a payment always requires an explicit amount — it will never refund "everything" by default — and the currency must be the original payment's, which Check a payment returns. Note that an sk_test_/rk_test_ key verifies perfectly and moves no real money, so a mis-pasted test key looks healthy until a real caller is on the line.
Support & ticketing
| Provider | Auth | Actions |
|---|---|---|
| Freshdesk | API key (Basic) | Create a support ticket (ticket.create). Set your Freshdesk domain (e.g. acme.freshdesk.com). Priority: 1=low, 2=medium, 3=high, 4=urgent. |
| Zendesk | API token (Basic) | Open a ticket (ticket.create), read it back (ticket.get), change its status or priority (ticket.update), add an internal note (ticket.add_comment), list a caller's tickets (ticket.list_requester), and find or create the caller (crm.lookup_contact by phone, crm.create_contact). Set your Zendesk URL (https://acme.zendesk.com) and the agent email the assistant acts as. Priority uses the same 1–4 scale as Freshdesk and is translated for you. |
Zendesk: create the token in Admin Center → Apps and integrations → APIs → Zendesk API, and make sure "Allow API token access" is ON there — with it off, a perfectly good token returns the same 401 as a wrong one. The agent email must belong to a real agent (an end-user account is refused), because tickets the assistant opens are submitted by that user. Notes the assistant writes are internal — visible to your support team, never emailed to the customer. Zendesk has nowhere to keep a phone number on a new ticket, so the caller's number is written into the ticket text; use Look up a contact first and pass the user ID into Create a support ticket when you want the ticket attached to their existing record. Statuses stop at solved — closed is reached by a Zendesk automation, never by the API.
Money-moving actions are always confirmed. Any
payment.*capability (e.g. Razorpay'spayment.link, Stripe'spayment.refund) makes the agent read the action back and wait for a verbal yes before it runs — even if you forget to tick the confirmation box. The one exception ispayment.status, which only ever reads: asking the caller for permission to look something up costs a turn and answers nothing. See Confirm before executing.
Step 2 — Attach a connection as an agent tool
Open the agent in the builder and go to the Tools step. Connections you've made appear under Workspace integrations · click to add — one card per action your connections offer (shared by all agents).
- Click the card for the action you want (e.g. Send WhatsApp on your Razorpay/Sheets/CRM connection). A tool is added to the agent.
- The stored tool references the connection by id and the capability — never the credentials:
{
"name": "send_whatsapp",
"kind": "connector",
"description": "Send a WhatsApp message to a phone number…",
"config": { "connectionId": "…", "capability": "whatsapp.send" },
"handoff": "Sending that over WhatsApp now."
}
- Optionally set a handoff line (spoken while the tool runs) and tick Confirm with the caller before running (see below).
- For actions that target a specific spreadsheet / base / form, complete the per-tool binding and click Load fields.
Don't have the connection yet? Use the + Add integration link right in the Tools step — see the slide-over.
Which account a connection uses
Each connected provider card shows the account that authorised it — for Google, the email captured at sign-in. This matters more than it looks: an org can connect several Google accounts, and a spreadsheet or calendar shared with one is invisible to the others. When a tool reports that it cannot find a document, the first thing to check is whether it is shared with the account on the card, not whether the ID is right.
Apps see the same list and can pin one, so a saved sync always reads as the same identity instead of whichever connection happens to resolve.
If a connection predates this and shows no account, reconnecting it captures one.
Per-tool binding ("Load fields")
Some actions need to know which target this particular tool points at — which spreadsheet, which Airtable base, which form, which Calendly event type. That choice lives on the tool, not the connection, so one connection serves any number of targets: a single Google Sheets connection can back 50 tools writing to 50 different sheets.
When you add such a tool, the card shows extra fields:
| Provider | Per-tool binding | Field discovery |
|---|---|---|
| Google Sheets | Spreadsheet ID (+ tab name, default Sheet1) | Reads the header row → one parameter per column |
| Airtable | Base ID + table | Reads the table schema → one parameter per writable field (computed & system fields excluded) |
| JotForm | Form ID | Reads the form's questions → one parameter per question (buttons, headings, etc. excluded) |
| Calendly | Event type (picked from a live dropdown of your active events) | — |
| Cal.com | Event type (live dropdown) + the business timezone | — |
| Stripe | Thank-you page URL (where Stripe sends the payer after checkout) | — |
| Typeform / Tally | Form ID | — (read-only lookups) |
For Sheets / Airtable / JotForm, after entering the target click Load fields. Telenow fetches the live columns/fields/questions and turns each into a parameter the model fills from the conversation. The discovered field names show as chips on the card.
- A green dropdown for the tab/event type. Where a setting can be enumerated (Sheets tabs, Calendly event types), the field becomes a live picker populated from the vendor; otherwise it's a text box where you paste an ID.
- Where to find the ID. Spreadsheet ID is in the sheet URL (
docs.google.com/spreadsheets/d/<ID>/edit); Airtable base ID is theapp…segment of the base URL; form IDs are in the form's public URL. - Re-load after schema changes. Discovery runs at configure time, not on every call. If you add or rename a column later, the card warns that "the target changed since these fields were loaded" — click Refresh fields so the agent collects the right columns.
Test action with sample data
On any connector tool card, click Test action with sample data. Telenow runs the real action once (no caller involved) with the JSON arguments you supply, applying the same binding and packing as a live call, and shows the raw result. Use it to confirm a row really lands in your sheet or a payment link really generates — before you publish.
Confirm before executing
For anything irreversible — send money, message a customer, write a record — tick Confirm with the caller before running. The first time the model calls the tool, Telenow doesn't execute it: it returns a "read this back and ask the caller to confirm" result, so the agent says something like "I'll send a payment link for ₹500 to +1… — shall I go ahead?" and only runs it on a later turn once the caller agrees. The read-back uses only the tool's arguments, never secrets.
Payments (payment.*) are forced on regardless of the checkbox — a careless config can't ship an unconfirmed money-moving tool. Full mechanics in Confirm before executing.
The "Add integration" slide-over
You don't have to leave the builder to connect a new vendor. In the Tools step, click + Add integration next to Workspace integrations. A right-hand slide-over opens with the full catalog (searchable, grouped by category). Pick a provider, fill the same connection form, and click Connect:
- API-key providers are verified on the spot; the connection's actions appear in the one-click list immediately.
- OAuth providers open consent in a new tab (your unsaved agent form is safe) — approve there, then return; the connections list refreshes when this window regains focus, so the new action shows up without a reload.
Pre-call lookups (screen-pop personalization)
A connector or your own API can run at the very start of a call, before the agent speaks, and drop the result into your context variables. That's how an agent opens with the caller's name, plan, or last order — a CRM "screen pop" for voice.
Set them up in the agent builder's Tools step, under Pre-call lookups · optional. Each lookup is one of two kinds:
Workspace integration lookup
Run a connected action (e.g. HubSpot's Look up a contact by phone) keyed on the caller, and map fields from the response into variables:
- Add a lookup, choose Workspace integration.
- Pick the connection and action.
- Set arguments using caller placeholders, e.g.
phone→{caller_number}. - Map response fields to variables, e.g.
customer_name→results.0.properties.firstname.value. The map uses a dot-path into the response (array indices supported:data.0.name).
Custom API lookup
Call your own HTTPS endpoint instead:
- Add a lookup, choose Custom API.
- Pick GET or POST and enter the URL with caller placeholders, e.g.
https://api.example.com/customers?phone={caller_number}. - Add an optional Bearer token and any headers; map response fields into variables the same way.
The placeholders available to a lookup are the trusted caller envelope only:
| Placeholder | Value |
|---|---|
{caller_number} | The caller's phone number (the dialed number for outbound; the ANI for inbound, which may be absent if withheld) |
{caller_identifier} | The identifier you passed when starting the call |
{caller_channel} | phone_inbound, phone_outbound, or web |
{session_id} | The call's id |
Custom API lookups never see
auth.*orconnection.*placeholders, only the caller envelope — so the URL must be public or carry its own bearer token.
Once mapped, the variables are available to the opening line and prompt: "Hi {customer_name}, I see you're on the {account_tier} plan." Works for outbound calls (and campaigns) and inbound calls.
Pre-call lookups are best-effort. They run concurrently with a short per-lookup timeout (~10 s); a slow or failed lookup logs a warning but never blocks the call — the agent simply starts without those variables. They run before any billable session exists, so they are not metered toward integration usage.
For why you should trust caller.number over a value the model collects, see caller identity.
MCP servers
Beyond the built-in catalog, an agent can call tools from any remote MCP (Model Context Protocol) server — your own, or a third party's. Manage these under Workplace → Integrations → MCP (a directory of curated servers plus your authenticated connections), and attach individual tools in the builder's Tools → Connect MCP server.
- Directory — curated remote servers (GitHub, Linear, Atlassian, Stripe, Notion, Asana, Sentry, PayPal). Pick one or paste a custom server URL.
- Verify — Telenow lists the server's tools. If the server requires sign-in, it reports
needsAuthand you start OAuth. - OAuth (DCR + PKCE) — for servers that need it, Telenow performs OAuth discovery and Dynamic Client Registration with PKCE, caches the discovery + client info, stores tokens encrypted, and refreshes them at dispatch time (same ~60 s pre-expiry logic as connectors). Static-token servers just take a pasted token.
- Attach tools — in the builder, verify the server, pick the tools you want, and they're stored inline on the agent as
kind: "mcp". Unlike connectors, MCP tools have no per-tool binding — each server is a single connection and the agent uses the tools you selected.
Only remote servers reachable over https:// are supported (an SSRF guard blocks loopback/private addresses); stdio / locally-spawned servers are not. A server can't be removed while an agent still references its tools. Full tool-spec details are in Tools & function calling.
Connect thousands of apps (aggregators)
The MCP directory also features aggregators — Composio, Pipedream Connect, and Zapier MCP — that front 250 to 7,000+ apps (Salesforce, HubSpot, Slack, Gmail, Sheets, and the long tail) behind one managed integration. Generate your personal MCP URL in the aggregator's dashboard, then add it under an agent's Tools → Connect MCP server. See Automation platforms.
OpenAPI import
Telenow can generate connector actions from an OpenAPI spec (request templates, parameter schemas, and response shaping derived from the spec). This is platform/admin-driven today and not yet a self-serve org upload. Until it is, the equivalent self-serve options are: a request-template (curl) tool for a single endpoint, or an MCP server / aggregator for a whole API surface.
Integration billing & plans
Integration usage can be metered against per-tier plans (Starter / Pro / Enterprise), but this is an admin-controlled feature that is OFF by default. When it's off — the default — every org has all categories and no quota, and nothing on this page is gated.
When an operator turns plans on, the Integrations page shows a banner with your plan, allowed categories, and this cycle's usage. The shipped tiers:
| Plan | Categories | Monthly connector-call quota | Overage |
|---|---|---|---|
| Starter | Messaging + Spreadsheets only | 1,000 | $0.005 / call |
| Pro | Messaging, Spreadsheets, Calendar, CRM, Support, Commerce, Forms, Productivity, Project | 10,000 | $0.003 / call |
| Enterprise | All | Unlimited | $0 |
- Connect-time gating — on a gated plan, connecting a provider whose category isn't allowed is rejected with a clear "upgrade to connect" message.
- Overage vs. hard cap — by default, going over quota accrues an overage charge (posted once per calendar month, for the previous month, via the billing ledger). A per-plan hard cap flag (admin-set) can instead block connector calls mid-call when over quota. The billing cycle is the UTC calendar month.
- Pre-call lookups are not metered (they run before a billable session exists).
See Billing & usage for how charges appear on your invoice.
Tips
- Name connections clearly. You'll pick them by label in the builder and pre-call lookups — "Sales Razorpay" beats "Razorpay" when you have two.
- Swap vendors without rework. Moving from one WhatsApp/CRM vendor to another? Connect the new one and repoint the tool's connection — the capability and the model's schema stay the same.
- Load fields after editing a sheet/base/form. Adding a column doesn't update existing tools automatically; click Refresh fields.
- Confirm anything irreversible. Tick Confirm with the caller for sends and writes; payments are always confirmed.
- Use pre-call lookups for warm openers, but keep them best-effort — never write a greeting that requires a variable a lookup might not return.
- Dry-run before you publish. The Test action bench on each tool card runs the real action once so you can verify it end-to-end.
Troubleshooting
| Symptom | Likely cause / fix |
|---|---|
| Provider isn't in Available | It's disabled in the catalog, or (for OAuth providers) the platform hasn't configured that vendor's OAuth app env vars. |
| OAuth sign-in fails or never returns | The provider's OAuth app isn't configured (*_OAUTH_CLIENT_ID/SECRET), or the registered redirect URI doesn't match …/api/public/integrations/oauth/callback. Ask your platform operator. |
| Connection shows Needs attention | The last test/refresh failed — the chip's tooltip and the row show the vendor's error. Click Edit to fix credentials/settings, then Test; for OAuth, Reconnect. |
| Connection shows Disconnected | An OAuth flow was started but consent wasn't completed — click Reconnect and approve. |
| Can't remove a connection | An agent still uses it (as a tool or pre-call lookup). Telenow names the agents — detach it there first. |
| "Load fields" errors | Re-check the spreadsheet/base/form ID and that the credential has read access to the target's schema. You can also paste the value manually if the picker can't load. |
| Connecting a CRM is rejected | Integration plans are on and your plan doesn't include that category — upgrade, or ask the operator to turn plans off. |
| Tool never fires on a call | The tool's description is too vague for the model to pick it, or a required argument can't be filled. See Tools & function calling. |
See also
- Tools & function calling — the full tool spec, confirm-before-execute, caller identity, placeholder filters
- Building agents — the Tools step in context
- WhatsApp — pairing + all five WhatsApp providers
- Context variables — variables pre-call lookups populate
- Automation platforms — Zapier / Make / n8n / viaSocket + the REST-hook API
- Billing & usage — how integration charges appear