Let your assistant answer questions about a customer's calendar
Section: DOC-IN-tools-connections-connected-apps#connect-your-agent-to-third-party-apps.
Build a “Connect calendar” button so a customer can ask your assistant what is on their schedule. The customer authorizes their account, your application confirms the connection, and the assistant uses that account's available tools in an ordinary conversation.
This recipe uses the optional hosted Pipedream Connect integration. It needs Pipedream enabled by your Travila operator, Google Calendar in the available catalog, a backend API key, and an authenticated application user. For a service you control, use your own MCP server.
Prepare the connection experience
Section: DOC-IN-tools-connections-connected-apps#what-you-dont-have-to-build.
Your application builds the Connect button, opens a hosted authorization page, and shows the resulting account in its integration settings. Pipedream manages the third-party credentials; your application does not store or refresh them.
Resolve X-On-Behalf-Of from the signed-in user's trusted application session for every request below. Use that same beneficiary for connection, confirmation and conversation. Never let an arbitrary body parameter choose whose calendar a request can access.
Keep “connected” distinct from “approved to act.” Reading a calendar and creating an event are different customer decisions. This recipe starts with answering a calendar question; add event creation only after designing its approval experience.
1. Offer the calendar connection
Section: DOC-IN-tools-connections-connected-apps#connecting-an-account.
Use catalog discovery to confirm that the integration is available. If it is not, leave the feature unavailable in your UI rather than sending the customer into a broken connect flow.
Find Google Calendar in the catalog
Section: DOC-IN-tools-connections-connected-apps#1-show-the-user-what-they-can-connect.
curl -X POST https://api.travila.ai/api/v1/integrations/pipedream/list-apps \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"q": "cal",
"sortKey": "APP_SORT_KEY_FEATURED_WEIGHT",
"sortDirection": "SORT_DIRECTION_DESC",
"limit": 20
}'
Reference: List connectable apps · Request fields.
A matching result provides the name and image for your Connect button and nameSlug for subsequent requests:
{
"data": [
{
"id": "app_1Q5hjR",
"nameSlug": "google_calendar",
"name": "Google Calendar",
"imgSrc": "https://assets.pipedream.net/s.v0/app_1Q5hjR/logo/orig",
"authType": "AUTH_TYPE_OAUTH",
"categories": [
"Productivity"
],
"featuredWeight": 12
}
],
"pageInfo": {
"count": 1,
"totalCount": 34,
"endCursor": "Y3Vyc29yOjE="
}
}
Reference: List connectable apps · Response fields.
Keep google_calendar, the returned slug, with the selected app. For a broader integration picker, use categories and app details. Paginate catalog results with pageInfo.endCursor as after; an empty data page ends the list.
Create the authorization link when the customer clicks Connect
Section: DOC-IN-tools-connections-connected-apps#2-create-a-connect-link.
curl -X POST https://api.travila.ai/api/v1/integrations/pipedream/create-connect-token \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"appSlug": "google_calendar",
"successRedirectUrl": "https://app.example.com/integrations?ok=1",
"errorRedirectUrl": "https://app.example.com/integrations?ok=0",
"state": "picker-session-8f3a"
}'
Reference: Start connecting an app · Request fields.
Open the returned connectLinkUrl unchanged:
{
"token": "ctok_5xyz...",
"connectLinkUrl": "https://pipedream.com/_static/connect.html?token=ctok_5xyz...&connectLink=true&app=google_calendar",
"expiresAt": "2026-08-10T10:04:11Z"
}
Reference: Start connecting an app · Response fields.
Create a fresh link for this attempt. It is single-use; read expiresAt instead of assuming a fixed lifetime. Include appSlug so the hosted page knows which app to connect.
Bind your application's attempt record to the signed-in session and compare the returned state with that record. The platform returns state unchanged; it is not a secret or proof of authorization. For an embedded Connect page, use the connect-token reference and specify the exact allowed framing origins.
Confirm the account before showing Connected
Section: DOC-IN-tools-connections-connected-apps#3-confirm-the-connection-landed.
After the customer returns, read their accounts:
curl -X POST https://api.travila.ai/api/v1/integrations/pipedream/list-accounts \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"app": "google_calendar"
}'
Reference: List the caller's connected accounts · Request fields.
{
"data": [
{
"id": "apn_kAHeAr9",
"name": "user@example.com",
"app": "google_calendar",
"healthy": true,
"createdAt": "2026-08-10T09:14:52Z"
}
],
"pageInfo": {
"count": 1,
"totalCount": 1
}
}
Reference: List the caller's connected accounts · Response fields.
Find the intended account and require healthy: true before showing it as usable. An absent healthy field means false. A redirect alone does not prove that authorization completed.
Save the returned account ID and display its account name so the customer can recognize the calendar. If no healthy account exists, show a retry of the Connect flow instead of claiming success.
2. Give this conversation access to the calendar
Section: DOC-IN-tools-connections-connected-apps#giving-the-model-a-connected-apps-tools.
Create a thread for the same application user with the connected app selected:
curl -X POST https://api.travila.ai/api/v1/llm/create-thread \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"conversationSettings": {
"mcpServers": [
{
"serverId": "pipedream:google_calendar",
"enabled": true
}
]
}
}'
Reference: Create a new conversation thread · Request fields.
Retain the returned conversation key. For an existing thread, use update-settings. Tool discovery happens on later turns, so completing a connection does not require recreating a thread.
An active agent profile replaces the conversation's MCP server list, even with an empty profile list. Put the calendar selection on the profile when you use one.
Start with the actions this feature needs
Section: DOC-IN-tools-connections-connected-apps#narrowing-what-the-model-can-reach.
Inspect the tools returned by tool discovery for pipedream:google_calendar. Select the actual read tools needed to answer schedule questions using allowlistToolPatterns. An empty allowlist allows all app tools, and blocklistToolPatterns takes precedence. Do not infer read-only behavior from a friendly tool description alone.
Set approval rules before testing tools that create or change events. Exact tool names and account inputs can vary with the configured integration; discovery supplies the contract your application should use. Follow Use and approve tools to display a proposed action and resolve its original pending call.
3. Ask about the schedule and inspect the result
Section: DOC-IN-tools-connections-connected-apps#what-a-tool-call-looks-like.
Send “What is on my calendar today?” using your normal message flow. Keep the selected account visible in your application's conversation or integration settings.
Inspect the tool-call record as well as the assistant's answer. A completed recipe has a successful calendar lookup against the intended account and an answer based on that result. If the tool reports an unavailable account, invalid input or authorization link, show that next step instead of an empty schedule.
Let the customer choose between work and personal accounts
Section: DOC-IN-tools-connections-connected-apps#when-a-user-has-more-than-one-account.
Run Connect again to add the other account, then use the discovered tool’s account selector when the customer chooses which calendar to read.
Show which account an action will use. If the customer's request is ambiguous, ask them to choose before acting. Invalid or missing required account selection is rejected, but a model instruction to choose correctly does not replace your application's approval experience.
Offer account management from the conversation
Section: DOC-IN-tools-connections-connected-apps#the-account-meta-tools.
The integration also exposes pd_list_accounts and pd_connect_account, so an assistant can answer which accounts are connected or obtain a link for another account. Your app should still confirm the resulting account before reporting success.
Recover when access expires during a conversation
Section: DOC-IN-tools-connections-connected-apps#choosing-when-the-user-connects.
Use the same application-driven Connect flow for a revoked or unhealthy account. Pause the dependent feature in your UI, let the user reconnect, confirm a healthy account, and then let them continue the task.
Recognize a connection request inside a tool result
Section: DOC-IN-tools-connections-connected-apps#what-an-unconnected-app-does.
Treat a returned connection request as a setup step. Confirm a working calendar lookup before showing the customer that the requested action completed.
Inspect the tool result in the returned messages or conversation state. If it contains a Connect URL, present a connection action rather than reporting a successful lookup. Never rewrite a returned Connect URL.
Validate a URL before opening it: require the expected HTTPS origin and path, expected parameters, no embedded credentials or fragment, and association with the current authenticated Connect attempt. A model-generated URL or matching text prefix is not enough.
Keep connection recovery in your application
Section: DOC-IN-tools-connections-connected-apps#option-1--connect-first-then-wire-the-tools.
The recommended path is the same as initial setup: create a fresh link for the selected app, open it, and confirm the account with a fresh lookup. This gives the customer a clear account choice and your application an observable result.
If the original calendar call may have changed something before failing, inspect the original call and the calendar before trying again. Reconnecting an account does not establish that an earlier action had no effect.
Optional: show the connection action through a client tool
Section: DOC-IN-tools-connections-connected-apps#option-2--hand-the-link-back-with-a-client-tool.
You can declare a client tool that carries a Connect URL into your UI. Your application validates and opens the URL, confirms the intended healthy account, and submits a truthful result for the original client-tool call.
A tool description cannot guarantee that the model forwards a link or calls the calendar again. Keep the application-driven flow available, and inspect the run outcome after submitting the client-tool result rather than promising automatic completion.
Offer Disconnect and account deletion
Section: DOC-IN-tools-connections-connected-apps#managing-connections.
Keep connection management reachable after setup. Customers need to see unhealthy connections and withdraw access without starting a conversation.
Repair an unhealthy account
Section: DOC-IN-tools-connections-connected-apps#health.
Read list-accounts for the current user and app. An absent or false healthy value with an error identifies an unusable connection. There is no repair operation; run Connect again and confirm the resulting account.
Disconnect the selected calendar
Section: DOC-IN-tools-connections-connected-apps#disconnecting-one-app.
Use the ID shown on the customer's connection screen:
curl -X POST https://api.travila.ai/api/v1/integrations/pipedream/delete-account \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"accountId": "apn_kAHeAr9"
}'
Reference: Disconnect one account · Request fields.
Read the account list again to confirm removal and stop selecting that account for new work. An account ID belonging to another user is returned as not found. Disconnecting cannot undo an already dispatched provider action; inspect pending work before reporting that all activity stopped.
Remove integration data when the customer leaves
Section: DOC-IN-tools-connections-connected-apps#offboarding-a-user-entirely.
For an application user who is deleting their account, remove all their Pipedream connections under that same authenticated beneficiary:
curl -X POST https://api.travila.ai/api/v1/integrations/pipedream/delete-external-user \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{}'
Reference: Delete the caller's integration data entirely · Request fields.
{
"deleted": true,
"accountsDeleted": 3
}
Reference: Delete the caller's integration data entirely · Response fields.
Verify the intended user’s connections are gone and retain unresolved external actions for follow-up. Removing these connections is irreversible.
Extend the feature beyond available tools
Section: DOC-IN-tools-connections-connected-apps#calling-an-apps-api-directly.
If a required operation is missing from the discovered tools, use the connected-account proxy to call a supported API on that app's domains with the user's own accountId. Your backend must authorize the specific operation; it does not pass through conversational tool approvals.
Check the upstream result before confirming the action. Use the response’s declared format and a supported provider download flow for large results.
Next recipes and reference
Section: DOC-IN-tools-connections-connected-apps#related.
- Use and approve tools: authorize changes before the assistant makes them.
- Build an assistant that researches the web: add public information to its answers.
- Connected apps API reference: exact catalog, connection and proxy contracts.
Document ID: DOC-IN-tools-connections-connected-apps. Section identities and revisions.