First-party app
Podium

Podium

Send messages, manage contacts and conversations, read reviews, calls and appointments, and subscribe to events in Podium, the customer-messaging platform for local businesses.

stable CommunicationMarketingCustomer Relationship Management

About

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.

App id
io.w6w.podium
Version
0.1.0
Author
w6w
Licence
MIT
Categories
Communication · Marketing · Customer Relationship Management

Overview

Podium 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.

Build with Podium

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.

Create Appointment

appointment-create

Create an appointment for a contact at a location. Requires scope `write_appointments`.

Get Appointment

appointment-get

Get one appointment by uid. Requires scope `read_appointments`.

List Appointments

appointment-list

List appointments, oldest change first. Requires scope `read_appointments`.

Get Call

call-get

Get one call by uid. Requires scope `read_phones`.

List Calls

call-list

List Podium Phones calls (calls synced from third-party call tracking are not listed). Requires scope `read_phones`.

Create Campaign

campaign-create

Create an automated campaign. Requires scope `write_campaigns`.

Get Campaign

campaign-get

Get one campaign by uid. Requires scope `read_campaigns`.

List Campaigns

campaign-list

List automated campaigns (the only kind the API manages), most recently updated first. Requires scope `read_campaigns`.

Send Campaign Message

campaign-message-send

Send a message to one recipient through a campaign. Not idempotent: every call sends. Requires scope `write_campaign_messages`.

Create Contact Attribute

contact-attribute-create

Create an application- or organization-level attribute definition that contacts can carry. Requires scope `write_contacts`.

List Contact Attributes

contact-attribute-list

List the contact attribute definitions owned by the token's application or organization. Not paginated. Requires scope `read_contacts`.

Opt Contact Out of Campaigns

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`.

Create or Update Contact

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`.

Delete Contact

contact-delete

Delete a contact identified by conversation uid, phone number or email. Requires scope `write_contacts`.

Get Contact

contact-get

Get one contact by conversation uid, phone number or email. Requires scope `read_contacts`.

List Contacts

contact-list

List contacts, optionally only those updated after a date. Requires scope `read_contacts`.

Add Tag to Contact

contact-tag-add

Add an existing tag to an existing contact. Requires scope `write_contacts`.

Create Contact Tag

contact-tag-create

Create an organization-level tag that can then be added to contacts. Requires scope `write_contacts`.

List Contact Tags

contact-tag-list

List every organization-level contact tag. Not paginated. Requires scope `read_contacts`.

Remove Tag from Contact

contact-tag-remove

Remove an existing tag from a contact. Requires scope `write_contacts`.

Opt Contact In to Transactional Messages

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`.

Opt Contact Out of Transactional Messages

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`.

Update Contact

contact-update

Update a contact identified by conversation uid, phone number or email. Only the fields you set are sent. Requires scope `write_contacts`.

Get Conversation

conversation-get

Get one conversation by uid. Requires scope `read_messages`.

List Conversations

conversation-list

List conversations, filtered by location and last activity. Requires scope `read_messages`.

Add Conversation Note

conversation-note-create

Add an internal note to a conversation. The note is not sent to the contact. Requires scope `write_messages`.

Update Conversation

conversation-update

Assign, reassign or close a conversation. Requires scope `write_messages`.

Send Data Feed Event

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`.

List Feedback

feedback-list

List feedback survey responses, newest first. Requires scope `read_feedback`.

Get Location

location-get

Get one location by uid. Requires scope `read_locations`.

List Locations

location-list

List the locations the token can access. Requires scope `read_locations`.

Get Message

message-get

Get one message from a conversation. Requires scope `read_messages`.

List Messages

message-list

List the messages in a conversation. Requires scope `read_messages`.

Send Message

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`.

Get Organization

organization-get

Get one organization by uid. Requires scope `read_organizations`.

Get Review

review-get

Get one review by uid. Requires scope `read_reviews`.

Create Review Invite Link

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`.

List Review Invites

review-invite-list

List review invites, newest first. Requires scope `read_reviews`.

List Reviews

review-list

List reviews, newest first. Requires scope `read_reviews`.

Respond to Review

review-response-create

Post a public response to a review. Requires scope `write_reviews`.

Get Review Summary

review-summary-list

Per-location review summary (counts and average rating). Requires scope `read_reviews`.

List Templates

template-list

List message templates. Template variables are not expanded by Send Message. Requires scope `read_templates`.

Get User

user-get

Get one user by uid. Requires scope `read_users`.

List Users

user-list

List the users who belong to any location the token can access. Requires scope `read_users`.

Create Webhook

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)`.

Delete Webhook

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.

Get Webhook

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.

List Webhooks

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.

Update Webhook

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>"
      }
    }
  ]
}

Here are some of the things you can do

  • Create Appointment

    perform
    appointment-create
  • Get Appointment

    read
    appointment-get
  • List Appointments

    read
    appointment-list
  • Get Call

    read
    call-get
  • List Calls

    read
    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.

Install
npm install @w6w/sdk
yarn add @w6w/sdk
pnpm add @w6w/sdk
deno add npm:@w6w/sdk
Code
import { 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);
Install the CLI
npm install -g @w6w/cli
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.

What the agent gets

Credentials it can't read

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.

A tool surface scoped to the caller

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.

A durable workflow in one call

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.

Health-aware discovery

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).

Request MCP access

Health checks

Podium declares its own checks, so its health is a property of the app rather than something the host guesses at.

service

Podium platform status

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.

quota

API request-rate headroom

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`.