CONNECT APP
Build with Quo
Communication
- API key
MCP
Give your agent Quo tools
Every Quo action is exposed as an MCP tool on Pipedream's remote server. Point a client at it with your end user's ID and Connect resolves that user's Quo account for each tool call — you store no tokens.
// accessToken: mint a short-lived token with the Connect SDK — see the MCP guide
const transport = new StreamableHTTPClientTransport(
new URL("https://remote.mcp.pipedream.net/v3"),
{
requestInit: {
headers: {
Authorization: `Bearer ${accessToken}`,
"x-pd-project-id": "{project_id}",
"x-pd-environment": "production",
"x-pd-external-user-id": "{external_user_id}", // any stable ID for this user in your system
"x-pd-app-slug": "openphone",
},
},
},
)
const mcp = new Client({ name: "my-agent", version: "1.0.0" })
await mcp.connect(transport)
const { tools } = await mcp.listTools()
// e.g. run Create Contact:
const result = await mcp.callTool({
name: "openphone-create-contact",
arguments: {
firstName: "First Name",
lastName: "Last Name",
},
})# access_token: mint a short-lived token with the Connect SDK — see the MCP guide
headers = {
"Authorization": f"Bearer {access_token}",
"x-pd-project-id": "{project_id}",
"x-pd-environment": "production",
"x-pd-external-user-id": "{external_user_id}", # any stable ID for this user in your system
"x-pd-app-slug": "openphone",
}
async with streamablehttp_client("https://remote.mcp.pipedream.net/v3", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
# e.g. run Create Contact:
result = await session.call_tool("openphone-create-contact", {
"firstName": "First Name",
"lastName": "Last Name",
})API PROXY
Call the Quo API directly
For an endpoint with no pre-built tool, the Connect proxy forwards your request to the Quo API with the connected user's credentials attached. You store no tokens and write no refresh logic.
const resp = await pd.proxy.get({
externalUserId: "{external_user_id}", // any stable ID for this user in your system
accountId: "apn_xxxxxxx",
url: "https://api.openphone.com/v1/phone-numbers",
})
// Any allowed Quo endpoint works here. Pipedream attaches the
// connected account's credentials to the outgoing request.# The path segment is the target URL, URL-safe base64 encoded:
# https://api.openphone.com/v1/phone-numbers
curl "https://api.pipedream.com/v1/connect/{project_id}/proxy/aHR0cHM6Ly9hcGkub3BlbnBob25lLmNvbS92MS9waG9uZS1udW1iZXJz?external_user_id={external_user_id}&account_id=apn_xxxxxxx" \
-H "Authorization: Bearer {access_token}" \
-H "x-pd-environment: production"SDK
Run Quo actions from your backend
Connect a user's Quo account once, then run Create Contact on their behalf from your own code — TypeScript, Python, or plain HTTP.
import { PipedreamClient } from "@pipedream/sdk"
const pd = new PipedreamClient({
projectId: process.env.PIPEDREAM_PROJECT_ID!,
clientId: process.env.PIPEDREAM_CLIENT_ID!,
clientSecret: process.env.PIPEDREAM_CLIENT_SECRET!,
projectEnvironment: "production",
})
const result = await pd.actions.run({
id: "openphone-create-contact",
externalUserId: "{external_user_id}", // any stable ID for this user in your system
configuredProps: {
openphone: { authProvisionId: "apn_xxxxxxx" },
firstName: "First Name",
lastName: "Last Name",
},
})from pipedream import Pipedream
pd = Pipedream(
client_id="{oauth_client_id}",
client_secret="{oauth_client_secret}",
project_id="{project_id}",
project_environment="production",
)
result = pd.actions.run(
id="openphone-create-contact",
external_user_id="{external_user_id}", # any stable ID for this user in your system
configured_props={
"openphone": {"authProvisionId": "apn_xxxxxxx"},
"firstName": "First Name",
"lastName": "Last Name",
},
)curl -X POST https://api.pipedream.com/v1/connect/{project_id}/actions/run \
-H "Content-Type: application/json" \
-H "X-PD-Environment: production" \
-H "Authorization: Bearer {access_token}" \
-d '{
"external_user_id": "{external_user_id}",
"id": "openphone-create-contact",
"configured_props": {
"openphone": { "authProvisionId": "apn_xxxxxxx" },
"firstName": "First Name",
"lastName": "Last Name"
}
}'TOOLS
Quo actions
On-demand operations your product or agent can configure and run on behalf of a connected user.
-
Create Contact
actionCreate a new contact in OpenPhone. Example: call with firstName="Jane", lastName="Doe", phoneNumbers=[{"name": "Mobile", "value": "+15551234567"}]→ returns the created contact record, including itsid. See the documentationWritev0.0.6 -
Create Task
actionCreate a task tied to an OpenPhone conversation. Example: call with conversationId="CN123abc", title="Follow up with customer re: onboarding", description="Customer asked about pricing tiers." → returns the created task record, including itsid. Use List Conversations or List Messages to find theconversationId. See the documentationWritev0.0.2 -
Delete Contact
actionPermanently delete a contact by ID. This cannot be undone. Example: call with contactId from List Contacts → the contact is removed and the response confirms deletion. See the documentationWritev0.0.2 -
Delete Task
actionPermanently delete a task by ID. This cannot be undone. Use List Tasks to find task IDs. Example: call with taskId="TK123abc" → the task is removed and the response confirms deletion. See the documentationWritev0.0.2 -
Get Call
actionRetrieve a single call by its ID, including its summary and transcript when available. Summary and transcript are fetched from OpenPhone's separate/summaryand/transcriptendpoints and merged into the result; they arenullif OpenPhone has not yet generated them. Use List Calls to find call IDs. Example: call with callId="AC123abc" → returns the call record withsummaryandtranscriptfields merged in. See the documentationRead-onlyv0.0.2 -
List Calls
actionRetrieve a paginated list of calls from OpenPhone. Requires both a phone number ID and a participant to scope the results — the API rejects calls missing either. Use List Phone Numbers to find valid phone number IDs. Example: call with phoneNumberId="PN123abc", participants="+15551234567" → returns up to 10 recent calls between that number and that participant. Usefieldsto return only specific fields per call. See the documentationRead-onlyv0.0.2 -
List Contacts
actionRetrieve a paginated list of contacts. Optionally filter by external IDs and/or sources. All contacts for the organization are returned only when neitherexternalIdsnorsourcesis provided. Example: call with no filters → returns up to 10 contacts for the organization. Usefieldsto return only specific fields per contact. See the documentationRead-onlyv0.0.2 -
List Conversations
actionRetrieve a paginated list of conversations. Can be filtered by user and/or phone numbers. Defaults to all conversations in the organization. Results are returned in descending order based on the most recent conversation. Example: call with no filters → returns up to 10 of the most recently active conversations. Usefieldsto return only specific fields per conversation. See the documentationRead-onlyv0.0.2 -
List From Options
actionList your OpenPhone phone numbers as selectable sender options, for use as thefromvalue in Send a Text Message. Example: call with no inputs → returns a list of{label, value}pairs, one per phone number, wherevalueis the phone number ID to pass asfrom. See the documentationRead-onlyv0.0.3 -
List Messages
actionRetrieve a paginated list of messages from OpenPhone, scoped to a phone number and a participant — both are required by the API. Optionally narrow further to one conversation withconversationId. Example: call with phoneNumberId="PN123abc", participants=["+15551234567"] → returns up to 10 recent messages between that number and that participant. Usefieldsto return only specific fields per message. See the documentationRead-onlyv0.0.2 -
List Phone Numbers
actionRetrieve the list of phone numbers and users associated with your OpenPhone workspace. Example: call with no inputs → returns each phone number'sid,number,name, and the users assigned to it. See the documentationRead-onlyv0.0.5 -
List Tasks
actionRetrieve a paginated list of tasks, optionally filtered by conversation. Use List Conversations or List Messages to find aconversationId. Example: call with no filters → returns up to 50 recent tasks across the organization. Usefieldsto return only specific fields per task. See the documentationRead-onlyv0.0.2 -
List Users
actionRetrieve a paginated list of users in your OpenPhone workspace. Use this to find a user's ID before assigning a task or filtering calls/messages/conversations byuserId. Example: call with no inputs → returns up to 10 users, each withid,name, andemail. See the documentationRead-onlyv0.0.3 -
Send a Text Message
actionSend a text message from one of your OpenPhone numbers to a recipient. Use List Phone Numbers (or List From Options) to find a validfromvalue. Example: call with from="PN123abc", to="+15551234567", content="Hi, following up on your request." → sends the message and returns the created message record. See the documentationWritev0.0.6 -
Update Contact
actionUpdate one or more fields on an existing contact. Only the fields you provide are changed; omitted fields are left as-is. Run List Contacts to find a contactId. Example: call with contactId from List Contacts and company="Acme Corp" → updates just the company field and returns the updated contact record. See the documentationWritev0.0.6 -
Update Conversation Status
actionUpdate the status of an OpenPhone conversation. SetconversationStatustodone,open, orread; the action routes to the corresponding OpenPhone endpoint (mark-as-done,mark-as-open,mark-as-read). Use List Conversations or List Messages to find theconversationId. Example: call with conversationId="CN123abc", conversationStatus="done" → marks the conversation done and returns the updated conversation. See the documentationWritev0.0.2 -
Update Task
actionUpdate an existing task's title and description by ID. NOTE: the OpenPhone update endpoint only modifiestitleanddescription(both required on every update); due date and assignee are managed via other endpoints. Use List Tasks to find task IDs. Example: call with taskId="TK123abc", title="Follow up (urgent)", description="Customer asked about pricing tiers." → updates both fields and returns the updated task record. See the documentationWritev0.0.2
-
New Call Recording Completed (Instant)
triggerEmit new event when a call recording has finished.Instantv0.0.4 -
New Incoming Call Completed (Instant)
triggerEmit new event when an incoming call is completed, including calls not picked up or voicemails left.Instantv0.0.4 -
New Message Received (Instant)
triggerEmit new event when a new message is receivedInstantv0.0.2 -
New Outgoing Call Completed (Instant)
triggerEmit new event when an outgoing call has ended.Instantv0.0.4
MULTI-APP
Use Quo with other popular apps
Most products don't stop at one integration. Pair Quo with the other apps your users rely on, and ship use cases that span both.
- App slug
- openphone
- Authentication
- API key
- Categories
- Communication
- Actions
- 17
- Triggers
- 4
- API proxy
- Available