Send messages, manage contacts and conversations, read reviews, calls and appointments, and subscribe to events in Podium, the customer-messaging platform for local businesses.
Podium ships in the w6w first-party pack. It declares 49 actions, 2 health checks, and the host runs its code in a sandbox that never sees the credential.
io.w6w.podiumPodium is the messaging and reviews platform local businesses use to talk to customers: text and email conversations, review invitations and replies, campaigns, appointments, phone calls and payments, all tied to one or more locations. This app drives the Podium API v4 from a workflow: create or update contacts and tag them, send an SMS or email, read and assign conversations, post internal notes, request and answer reviews, list calls, feedback and appointments, push events into a data feed, and manage webhook subscriptions. Authentication is OAuth 2 against a Podium developer app.
Three routes to the same 49 actions. The Workflow tab is generated from Podium's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.
appointment-create Create an appointment for a contact at a location. Requires scope `write_appointments`.
appointment-list List appointments, oldest change first. Requires scope `read_appointments`.
call-list List Podium Phones calls (calls synced from third-party call tracking are not listed). Requires scope `read_phones`.
campaign-list List automated campaigns (the only kind the API manages), most recently updated first. Requires scope `read_campaigns`.
campaign-message-send Send a message to one recipient through a campaign. Not idempotent: every call sends. Requires scope `write_campaign_messages`.
contact-attribute-create Create an application- or organization-level attribute definition that contacts can carry. Requires scope `write_contacts`.
contact-attribute-list List the contact attribute definitions owned by the token's application or organization. Not paginated. Requires scope `read_contacts`.
contact-campaign-opt-out Opt a phone number out of campaign (marketing) messages. Podium requires your application to be whitelisted by support for this endpoint. Requires scope `write_contacts`.
contact-create Create a contact. If a contact with the same phone number, email or conversation uid already exists it is updated instead (upsert). Podium answers 202: the write is queued. Requires scope `write_contacts`.
contact-delete Delete a contact identified by conversation uid, phone number or email. Requires scope `write_contacts`.
contact-get Get one contact by conversation uid, phone number or email. Requires scope `read_contacts`.
contact-list List contacts, optionally only those updated after a date. Requires scope `read_contacts`.
contact-tag-add Add an existing tag to an existing contact. Requires scope `write_contacts`.
contact-tag-create Create an organization-level tag that can then be added to contacts. Requires scope `write_contacts`.
contact-tag-list List every organization-level contact tag. Not paginated. Requires scope `read_contacts`.
contact-tag-remove Remove an existing tag from a contact. Requires scope `write_contacts`.
contact-transactional-opt-in Reverse a previous transactional opt-out. Separate from campaign consent. Podium requires your application to be whitelisted by support. Requires scope `write_contacts`.
contact-transactional-opt-out Opt a phone number out of transactional messages (the state a STOP reply produces). Opting out an already opted-out number succeeds. Podium requires your application to be whitelisted by support. Requires scope `write_contacts`.
contact-update Update a contact identified by conversation uid, phone number or email. Only the fields you set are sent. Requires scope `write_contacts`.
conversation-list List conversations, filtered by location and last activity. Requires scope `read_messages`.
conversation-note-create Add an internal note to a conversation. The note is not sent to the contact. Requires scope `write_messages`.
conversation-update Assign, reassign or close a conversation. Requires scope `write_messages`.
data-feed-event-send Push one event (or a list of events) through a data feed to trigger a Podium automation. The body shape depends on how the data feed was configured. Requires scope `write_data_feed_event`.
feedback-list List feedback survey responses, newest first. Requires scope `read_feedback`.
location-list List the locations the token can access. Requires scope `read_locations`.
message-send Send an SMS or email from a Podium location to a phone number or email address. Not idempotent: every call sends a message. Variables in template text are NOT expanded by Podium. Requires scope `write_messages`.
review-invite-create Create a review invitation link for a contact. Podium: never reuse a link across contacts — create a fresh one per contact. Requires scope `write_reviews`.
review-invite-list List review invites, newest first. Requires scope `read_reviews`.
review-response-create Post a public response to a review. Requires scope `write_reviews`.
review-summary-list Per-location review summary (counts and average rating). Requires scope `read_reviews`.
template-list List message templates. Template variables are not expanded by Send Message. Requires scope `read_templates`.
user-list List the users who belong to any location the token can access. Requires scope `read_users`.
webhook-create Subscribe a URL to Podium events for a location or organization. The signing `secret` is write-only here: Podium echoes it back in every webhook object and this action removes it from the result. Requires scope `(depends on the event types)`.
webhook-delete Delete a webhook. The signing `secret` is write-only here: Podium echoes it back in every webhook object and this action removes it from the result. Requires no scope.
webhook-get Get one webhook by uid. The signing `secret` is write-only here: Podium echoes it back in every webhook object and this action removes it from the result. Requires no scope.
webhook-list List the webhooks created by the user who authorized the application. The signing `secret` is write-only here: Podium echoes it back in every webhook object and this action removes it from the result. Requires no scope.
webhook-update Change a webhook's URL, events, secret or disabled flag; unset fields are left alone. The signing `secret` is write-only here: Podium echoes it back in every webhook object and this action removes it from the result. Requires scope `(depends on the event types)`.
A workflow step names the app and the action, and the editor fills in the
connection when you pick one. This is the Step shape from the
workflow spec, carrying Podium's real ids.
{
"manifestVersion": "2",
"name": "podium-example",
"steps": [
{
"id": "appointment-create",
"uses": {
"app": "io.w6w.podium",
"action": "appointment-create",
"connection": "conn_YOUR_CONNECTION_ID"
},
"with": {
"locationUid": "<locationUid>",
"contactName": "<contactName>",
"contactPhoneNumber": "<contactPhoneNumber>"
}
}
]
}appointment-create appointment-get appointment-list call-get call-list +44 more actions available
Every app-specific value here is a blank you have to fill in. An
app action is reached through the connection that authenticates it, so the
address is a connection id, not the app id — and connections belong to your account,
so a public page cannot know yours. Create one for Podium, then fill in
the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the
parameters that action declares. The call itself is real — the shape is transcribed
from the studio's own snippet builder, which prints the same kind of blanks — but
nothing in it is specific to Podium. The Workflow tab is where this app's
real ids are.
npm install @w6w/sdkyarn add @w6w/sdkpnpm add @w6w/sdkdeno add npm:@w6w/sdkimport { W6wClient, isActionRun } from "@w6w/sdk";
// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();
const envelope = await client.run({
urn: "conn_YOUR_CONNECTION_ID",
action: "appointment-create",
payload: {
locationUid: "<value>",
contactName: "<value>",
contactPhoneNumber: "<value>",
datetime: "<value>",
// durationMin: "<value>",
// assignedUserUid: "<value>",
// note: "<value>",
// status: "<value>",
// type: "<value>",
},
});
if (isActionRun(envelope)) console.log(envelope.value); npm install -g @w6w/cli w6w run conn_YOUR_CONNECTION_ID --action appointment-create --payload '{"locationUid":"<value>","contactName":"<value>","contactPhoneNumber":"<value>","datetime":"<value>"}' Give an AI agent Podium — without giving it Podium's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.
One tool call{
"name": "w6w_invoke",
"arguments": {
"ref": "app:io.w6w.podium#appointment-create",
"input": {
"locationUid": "<locationUid>",
"contactName": "<contactName>",
"contactPhoneNumber": "<contactPhoneNumber>"
}
}
}
Every tool names its target with a single ref. The
app: form above doesn't name a connection at all — the
host resolves which of the caller's Podium connections to sign
with, and refuses rather than guesses when the answer is ambiguous.
The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.
Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.
Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.
Podium's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.
The MCP surface is part of the hosted platform. Podium itself is MIT, and the runtime that executes it is source-available (FSL).
Podium declares its own checks, so its health is a property of the app rather than something the host guesses at.
Instatus feed for status.podium.com. The verdict tracks the `Public API` component — the surface every action calls — not the page roll-up, which also covers the web app, mobile, webchat and phones. Other components are reported for attribution only.
Requests remaining in the current one-minute window (300 per minute), read from the `ratelimit-*` response headers of a signed, scope-free `GET /v4/webhooks`.