---
updatedAt: 2026-08-17T12:55:16.000Z
agentTools:
  projectIndex: https://docs.lodgestory.com/llms.txt
---

# List survey forms

Active (non-archived) survey forms with their live version numbers. Use a formId with the invite and response endpoints.

# OpenAPI definition

````json
{
  "openapi": "3.0.0",
  "paths": {
    "/api/wp-crm/surveys/{organisationId}/forms": {
      "get": {
        "description": "Active (non-archived) survey forms with their live version numbers. Use a formId with the invite and response endpoints.",
        "operationId": "listForms",
        "parameters": [
          {
            "name": "organisationId",
            "required": true,
            "in": "path",
            "description": "Your organisation UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "JWT-auth": []
          }
        ],
        "summary": "List survey forms",
        "tags": [
          "Surveys"
        ]
      }
    }
  },
  "info": {
    "title": "Lodgestory WhatsApp CRM API",
    "description": "## Overview\n\n  The Lodgestory WhatsApp CRM API allows businesses to integrate their Property Management Systems (PMS) with the Lodgestory WhatsApp CRM platform. Through this API you can programmatically send messages, browse and filter chats, read full conversation history, manage chat assignment, browse channels, dispatch pre-approved WhatsApp templates, create and update the templates themselves (including header media), onboard your tenants' own WhatsApp numbers through hosted links, and generate CRM reports.\n\n  ## Authentication\n\n  All endpoints (except `POST /api/wp-crm/token`) require a **Bearer JWT token** in the `Authorization` header.\n\n  **How to authenticate:**\n  1. Call `POST /api/wp-crm/token` with your `api_token` and `user_id` (email) to receive a JWT.\n  2. Pass the JWT in subsequent requests as: `Authorization: Bearer <token>`\n  3. Tokens are valid for **10 days**.\n\n  ## Quick Start\n\n  ```\n  Step 1 → POST /api/wp-crm/token              → Get your JWT\n  Step 2 → GET  /api/wp-crm/channels/:orgId     → List your channels\n  Step 3 → POST /api/wp-crm/messaging/create-chat → Create a chat with a contact\n  Step 4 → POST /api/wp-crm/messaging/send-message → Send a message\n  Step 5 → POST /api/wp-crm/reports/:orgId          → Request a report\n  Step 6 → GET  /api/wp-crm/reports/:orgId          → Poll until status is COMPLETED\n  Step 7 → GET  /api/wp-crm/reports/:orgId/:id/download → Download the report CSV\n  ```\n\n  **Browsing the inbox (read-only):**\n  ```\n  Step B1 → GET /api/wp-crm/chats/:orgId                    → List & filter chats (status, channelIds, assignedToUserIds/TeamIds, unassigned, unanswered, priority, archived, labelIds, search, updatedAfter/Before; sort + paginate via offset/limit, hasMore)\n  Step B2 → GET /api/wp-crm/chats/:orgId/:chatId            → Get one chat (contact, channel, status, assignees, teams, labels, last message)\n  Step B3 → GET /api/wp-crm/chats/:orgId/:chatId/messages   → View the conversation (newest page first; oldest→newest within a page; page back with offset, hasMore)\n  ```\n  Example: `GET /api/wp-crm/chats/{orgId}?status=open&unanswered=true&channelIds={channelId}&limit=20` returns the open, awaiting-reply chats on a channel; then `GET /api/wp-crm/chats/{orgId}/{chatId}/messages?limit=50` returns that chat's latest 50 messages oldest→newest. The `chatId` is the same id `create-chat` returns and the assignment endpoints use. Listing is **org-wide** for `CRM_ADMIN`/`ACCOUNT_OWNER`/`CRM_BOT`; viewing a conversation is a pure read and does **not** mark the chat as seen. Get `channelId`/`labelId`/user & team IDs to filter by from the Channels and Directory endpoints.\n\n  **Managing chat assignment:**\n  ```\n  Step A → GET  /api/wp-crm/directory/:orgId/users  → List assignable users (get userIds)\n  Step B → GET  /api/wp-crm/directory/:orgId/teams  → List teams (get teamIds)\n  Step C → POST /api/wp-crm/chat-assignments/:orgId/users/assign → Assign users + set a primary\n  Step D → POST /api/wp-crm/chat-assignments/:orgId/teams/assign → Assign a team\n  Step E → GET  /api/wp-crm/chat-assignments/:orgId/chats/:chatId/assignees → Verify the assignment\n  ```\n  The `chatId` used by the assignment endpoints is the same `chatId` returned by `create-chat`.\n\n  **WhatsApp groups:**\n  ```\n  Step G1 → POST /api/wp-crm/groups/:orgId                                → Create a group (async — returns requestId)\n  Step G2 → GET  /api/wp-crm/groups/:orgId/creation-status/:requestId     → Poll until status is \"created\" → the group's chatId\n  Step G3 → POST /api/wp-crm/groups/:orgId/:chatId/participants           → Add members (max 8 per call)\n  Step G4 → GET  /api/wp-crm/groups/:orgId/:chatId/invite-link            → Or share the invite link instead\n  Step G5 → POST /api/wp-crm/messaging/send-message                       → Message the group (same chatId)\n  Step G6 → POST /api/wp-crm/chat-assignments/:orgId/users/assign         → Assign agents to the group (same chatId)\n  ```\n  Groups require a `WHATSAPP_OFFICIAL` channel whose number is an **Official Business Account** (ineligible numbers get a 422). Creation is asynchronous — instead of polling, subscribe to the `group.created` webhook, which delivers the `chat_id` alongside your `request_id`. The group's `chatId` behaves like any other chat: it appears in the Chats endpoints and works with send-message and the assignment endpoints. With `joinApprovalMode` on (the default), approve invite-link joiners via the join-requests endpoints (pending joiners appear as `PENDING` participants with a `joinRequestId`).\n\n  **Managing templates:**\n  ```\n  Step T1 → POST /api/wp-crm/templates/:orgId/media           → (only for media headers) turn a public HTTPS URL into a header_handle\n  Step T2 → POST /api/wp-crm/templates/:orgId?channelId=…     → Submit a new template to Meta for review\n  Step T3 → GET  /api/wp-crm/channels/:orgId/templates        → Poll approval status (or subscribe to template.status_updated)\n  Step T4 → POST /api/wp-crm/messaging/send-message           → Send it (type: template) once APPROVED\n  ```\n  Edit an existing template with `PUT /api/wp-crm/templates/:orgId/:templateId?channelId=…` — send only the parts you're changing; unchanged components are merged in before resubmission to Meta. Use POSITIONAL parameters (`{{1}}`, `{{2}}`) in templates you plan to send through this API.\n\n  **Hosted channel onboarding (white-label):**\n  ```\n  Step H1 → POST /api/wp-crm/channel-onboarding/:orgId/links       → Mint a one-time hosted signup link (tenantRef + redirectUrl)\n  Step H2 → (your tenant) opens the returned onboardingUrl          → Completes Meta Embedded Signup on a neutral hosted page\n  Step H3 → GET  /api/wp-crm/channel-onboarding/:orgId/links/:id    → Poll until COMPLETED → the new channelId\n  ```\n  On completion the tenant is redirected to your `redirectUrl` with `status`, `tenant_ref`, and `channel_id` query params, and `channel.connected` fires on your registered webhooks. The `onboardingUrl` is returned exactly once, at creation.\n\n  **Voice (telephony):**\n  ```\n  Step V1 → GET  /api/wp-crm/voice/:orgId/agents          → Find an agent (hasAgentNumber=true)\n  Step V2 → POST /api/wp-crm/voice/:orgId/calls           → Place a click-to-call\n  Step V3 → GET  /api/wp-crm/voice/:orgId/calls           → Read call history / status\n  Step V4 → GET  /api/wp-crm/voice/:orgId/calls/:id/recording → Resolve a recording URL\n  Step V5 → POST /api/wp-crm/voice/:orgId/mask-configs/:configId/customers → Add a masked-connect customer\n  ```\n  The public voice API is opt-in per organisation (subject to daily/monthly call caps + a destination allowlist). Subscribe to `call.answered` (mid-call, the moment the call is picked up — for screen-pops), `call.completed`, `call.missed`, `call.recording_available`, and `call.transcript_available` webhooks to receive call events instead of polling.\n\n  ## Reports\n\n  Generate and download CRM reports as CSV files. Supported report types: **CHAT**, **CONTACT**, **TICKET**, **CALL_LOG**, **GOAL**, **BOOKING**, **FOLLOW_UPS**, **SURVEY_RESPONSES**, **FLOW_RESPONSES**, **CHAT_STATE_HISTORY**, **DISPOSITIONS**, **LEAD**, **LEAD_ACTIVITY**.\n\n  Reports are generated **asynchronously** — request one, poll the list endpoint until its status changes to `COMPLETED`, then call the download endpoint to get a presigned S3 URL.\n\n  - **Rate limit:** 1 report per type per organisation every 5 minutes.\n  - **Required role:** Only users with `CRM_ADMIN` or `ACCOUNT_OWNER` role can request, list, or download reports.\n  - **Organisation scoping:** Your JWT is cryptographically bound to a specific organisation. Requests targeting a different organisation will fail with 401.\n\n  ## Rate Limits & Constraints\n\n  - Template messages are only supported on **WHATSAPP_OFFICIAL** channels.\n  - Groups need a **WHATSAPP_OFFICIAL** channel with an Official Business Account; group creation is limited to 20/minute, participant changes to 8 numbers per request.\n  - Channels, chats, groups, and templates are scoped to your organisation — cross-org access is denied.\n  - Media can be sent via public URL or base64-encoded string.\n  - Template management: 20 creates, 30 updates, and 10 header-media uploads per organisation per minute; header-media URLs must be public HTTPS, max 25 MB.\n  - Onboarding links are single-completion and expire (default 7 days, max 30); the raw link URL is only ever returned at creation.\n  - Reports are limited to 1 per type per organisation every 5 minutes.\n\n  ## Error Codes\n\n  | Code | Meaning |\n  |------|---------|\n  | 400  | Invalid request body or missing required fields |\n  | 401  | Missing, expired, or invalid JWT token |\n  | 403  | Insufficient role, or resource does not belong to your organisation |\n  | 404  | Requested resource not found |\n  | 409  | Conflict (e.g., messaging your own channel number) |\n  | 429  | Too many requests — per-organisation rate limit exceeded |\n  | 500  | Internal server error |\n  ",
    "version": "1.0",
    "contact": {
      "name": "Lodgestory API Support",
      "url": "https://lodgestory.com",
      "email": "support@lodgestory.com"
    }
  },
  "servers": [
    {
      "url": "https://api.lodgestory.com",
      "description": "Production"
    }
  ],
  "components": {
    "securitySchemes": {
      "JWT-auth": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http",
        "description": "Enter the JWT token obtained from POST /api/wp-crm/token"
      }
    }
  }
}
````