# Org & Chat Assistant
Source: https://docs.periskope.app/ai/agent/ai-assistant
Periskope has two AI assistants built into the interface — the **Org Assistant** and the **Chat Assistant**. Each serves a different purpose, and together they cover everything from bulk workspace actions to per-conversation intelligence.
***
## Chat Assistant
The Chat Assistant is available inside any individual chat. When you open a chat, look for the right-side panel — click the **AI tab** to access it.
The Chat Assistant gives you quick, context-aware actions specific to the conversation you're in — without needing to read through the entire chat history.
***
### What the Chat Assistant Can Do
When you open the AI tab in a chat, you'll see a set of built-in quick actions:
| Action | What it does |
| :- | :- |
| Summarise this conversation | Generates a concise summary of the chat so far |
| Raise a ticket on the important messages | Identifies key messages and creates a ticket automatically |
| What's the sentiment? | Analyses the tone of the conversation — positive, neutral, or frustrated |
| Reply to the conversation | Drafts a suggested reply based on the context of the chat |
You can also type a custom question in the text field at the bottom of the AI panel:
```text theme={null}
Has this customer mentioned billing issues before?
```
```text theme={null}
What was the last thing we promised this customer?
```
```text theme={null}
Summarise only the unresolved issues in this chat.
```
***
## Org Assistant
The Org Assistant is available across every page in Periskope. Look for the **AI icon in the bottom-right corner** of the screen — clicking it opens the Org Assistant in a side panel.
Unlike the AI Agent (which talks to your customers), the Org Assistant works for your team. It understands your workspace, can access chat data, and can take real actions — all from a single conversation.
***
### What the Org Assistant Can Do
| Capability | What you can ask |
| :- | :- |
| Bulk chat management | Update labels, assign chats, send private notes |
| Ticket & task updates | Change status, priority, or owner across multiple tickets |
| Data lookup | Fetch custom properties, search messages by timeframe |
| Custom tool actions | Extend trials, fetch account details, trigger API actions |
| Knowledge Base upkeep | Find gaps, flag outdated articles, spot duplicates, draft new entries |
***
### Manage Multiple Chats at Once
One of the most powerful — and least obvious — things the Org Assistant can do is act across many chats at the same time. Instead of opening each chat individually, just tell it what you need.
#### Update labels across multiple chats
Apply, update, or remove labels across a group of chats in one instruction. Useful after a busy period when chats need to be re-categorised, or when tagging a batch of conversations for a campaign or audit.
**Example prompts:**
```text theme={null}
Add the label "Escalated" to all open chats assigned to Priya.
```
```text theme={null}
Remove the "Pending" label from all chats updated today.
```
#### Assign multiple chats to one person
Hand off an entire batch of chats to a team member in a single request. Useful during shift changes or when redistributing workload.
**Example prompts:**
```text theme={null}
Assign all unassigned chats from today to Rahul.
```
```text theme={null}
Move all chats labelled "VIP" to Sara.
```
#### Send private notes to multiple chats
Drop an internal note into several chats simultaneously — helpful when you need to flag context or instructions for your team across multiple active conversations at once.
**Example prompts:**
```text theme={null}
Send a private note to all chats with the "Renewal" label:
"Follow up with the customer about their renewal before Friday."
```
#### Activate the AI Agent on multiple chats
Switch on the AI Agent across several chats at the same time, without toggling each one manually.
**Example prompts:**
```text theme={null}
Activate the AI Agent on all chats that have been idle for more than 2 hours.
```
***
### Handle Tasks & Tickets in Bulk
#### Update multiple tickets or tasks
Describe the change you need and let the Org Assistant apply it across all matching tickets at once — no need to open each one individually.
**Example prompts:**
```text theme={null}
Mark all open tickets tagged "Bug" as high priority.
```
```text theme={null}
Reassign all tickets under Alex to the general queue.
```
***
### Look Up Chat Data Instantly
#### Get custom properties of any chat
Every chat can have custom properties attached — things like `org_id`, plan type, account tier, or renewal date. Instead of opening the chat to look these up, just ask.
**Example prompts:**
```text theme={null}
What is the org_id for Acme Corp?
```
```text theme={null}
What plan is the customer in the TechBase chat on?
```
#### Search messages within a specific timeframe
Search for specific messages across a set of chats within a date range. Useful for audits, escalation reviews, or tracking down a conversation.
**Example prompts:**
```text theme={null}
Find all messages from last week where a customer mentioned "refund".
```
```text theme={null}
Search chats labelled "Enterprise" for any messages about downtime in the last 30 days.
```
***
### Keep the Knowledge Base Up to Date
On the [Knowledge Base](/ai/agent/training) page, the Org Assistant reads your actual FAQs, documents, and self-learned entries before responding — it isn't guessing. Open the panel there and you'll see suggested prompts for common upkeep tasks:
| Suggested Prompt | What it does |
| :- | :- |
| Find gaps | Surfaces topics customers ask about often that aren't documented anywhere |
| Review outdated articles | Flags entries that reference prices, policies, or procedures that may have changed |
| Find duplicates | Points out overlapping or conflicting entries covering the same topic |
| Create new article | Drafts a new knowledge base entry based on recent common questions |
Clicking a suggested prompt fills the message box with that text — it doesn't send automatically. Review or edit it, then hit send.
**Example prompts:**
```text theme={null}
Find knowledge base articles that may be outdated or need updating.
```
```text theme={null}
Do a deep search of the knowledge base. Look for entries that reference specific prices, policies, or procedures that may have changed. Flag each one and explain why.
```
The assistant searches the knowledge base directly and grounds its answer in what it finds — it will tell you which entries it flagged and why, rather than giving a generic response.
***
### Custom Tool Actions
If your workspace has Custom Tools configured, the Org Assistant can call them directly — no tab switching, no manually looking up IDs.
When you ask it to perform an action, the Org Assistant will:
1. Understand what you need from your message
2. Look up required values — like `org_id` — from the chat's custom properties automatically
3. Call the relevant Custom Tool with the right parameters
4. Confirm the result back to you in the conversation
#### Example — Extending a customer's trial
```text theme={null}
Extend the trial for Acme Corp by 7 days.
```
The assistant finds the `org_id` from the chat's custom properties and calls your trial extension tool automatically — no need to open the chat.
#### Example — Fetching account details
```text theme={null}
What is the current subscription status for GlobalTech?
```
> **Note:** For custom tool actions to work, the relevant tool must be active under AI > Custom Tools, and required properties like `org_id` must be present in the chat's custom properties.
# AI Dictate
Source: https://docs.periskope.app/ai/agent/ai-dictate
What if you didn't have to type a single word to manage your customer conversations? Periskope lets you do everything with just your voice — from crafting replies to running actions across your workspace.
***
## Dictation Mode in the Chat
When you're inside a chat and want to send a reply, click the **dictation button** to start recording — and click it again when you're done. You can also use the keyboard shortcut **Ctrl+D** on Windows or **Cmd+D** on Mac.
The AI has the full context of the conversation. It listens to what you say, understands the situation, and crafts a response for you — ready to send.
### How it works
1. Open any chat
2. Click the **dictation button** to start recording (or press **Ctrl+D** / **Cmd+D**)
3. Speak your instruction — for example:
```text theme={null}
Tell them about our pricing plans and ask if they'd like to book a demo.
```
4. Click the dictation button again to stop recording
5. The AI generates a reply based on your instruction and the conversation context
6. Want to refine it? Click the dictation button again and say:
```text theme={null}
Make the tone more formal.
```
7. The message updates instantly — review and hit send
No typing. No copy pasting. Just speak, review, and send.
> **Tip:** You don't need to dictate the exact reply word for word — just tell the AI what you want to communicate and it handles the wording for you.
***
## Voice with the Org Assistant
The same voice feature works with the Org Assistant too. Instead of typing your instructions, just click the **microphone icon** in the Org Assistant panel and speak.
### How it works
1. Open the Org Assistant from the bottom-right corner of any page
2. Click the **microphone icon**
3. Speak your instruction — for example:
```text theme={null}
How many unread chats do I have today?
```
4. Review what was transcribed
5. Click **Send** — it's done instantly
Any action you'd normally type to the Org Assistant, you can now just say out loud.
***
## Voice with the Chat Assistant
You can use voice with the Chat Assistant as well. Open any chat, click the microphone in the Chat Assistant panel, and ask anything about that conversation — without typing a single word.
### How it works
1. Open a chat and go to the **AI tab** in the right panel
2. Click the **microphone icon**
3. Ask anything about the conversation — for example:
```text theme={null}
Summarise this conversation.
```
```text theme={null}
What's the sentiment of this chat?
```
```text theme={null}
What are the most important messages here?
```
4. The assistant responds instantly based on the chat context
***
## Why This Matters
Your team moves faster when they're not stuck typing. With voice, everything just flows — whether it's managing your workspace or crafting the perfect reply, you can do it all hands-free.
***
# Built-in Tools
Source: https://docs.periskope.app/ai/agent/built-in-tools
Configure the built-in actions your AI Agent can take in conversations
Built-in Tools are actions the AI Agent can take natively within Periskope — no external API required. Access them through **AI** > **Tools**, on the **Built-in Tools** tab.
Each tool can be toggled on or off independently. When a tool is enabled, the AI will use it autonomously based on conversation context and the rules you configure.
***
## AI Training
When enabled, the AI will look for messages answered by team members in ongoing conversations and use them to train itself automatically.
This feeds directly into the [Self-Learned](/ai/agent/training#self-learned-context) tab in the Knowledge Base. If approval is set to manual on the [Self-Training](/ai/agent/self-training) page, these entries appear as pending until you approve them.
***
## Allow AI to Send Messages
Controls whether the AI Agent can send messages directly in chats.
* **On**: The AI actively responds to customers
* **Off**: The AI operates as a **passive assistant** — it processes conversations and may create internal notes or tickets, but will not send any customer-facing messages
Use the passive mode if you want AI assistance for your team (e.g., auto-creating tickets or summarizing context) without having it talk directly to customers.
***
## Allow AI to Create Tickets
When enabled, the AI can automatically create tickets based on predefined rules.
You define the rules in plain language directly in the tool's text field. The AI reads this rule when deciding whether to raise a ticket.
**Example rules:**
```text theme={null}
Create a ticket when:
1) Customer reports a damaged delivery
2) Request for custom orders
3) Customer reports a payment failure or billing issue
```
Be specific about the conditions. The AI uses this rule as a prompt, so precise instructions like "create a ticket when the customer reports they cannot log in after 3 attempts" work better than "create tickets for login issues".
***
## Allow AI to Create Private Notes
When enabled, the AI can create private notes visible only to your internal team — not to customers.
Use this to have the AI:
* Flag conversations that need human follow-up
* Summarize context for a team member being handed a conversation
* Tag specific team members when their attention is needed
**Example rules:**
```text theme={null}
For minor questions, you may raise a private note tagging @rohosen.bhattacharya@hashlabs.dev.
If the question is about automation rules, tag @harsh.gour@hashlabs.dev.
```
The AI uses these rules as instructions for when and how to create private notes, including who to tag.
***
## How Tools Work Together
The AI's built-in tools work in combination. A typical flow might be:
1. Customer asks about a delivery issue
2. AI uses its **Knowledge Base** to provide an initial response
3. AI determines the issue requires escalation based on your ticket rules
4. AI **creates a ticket** and tags the relevant team member via a **private note**
5. AI informs the customer that their issue has been escalated
All of this happens autonomously, based on the rules you configure.
## Next Steps
* [**Custom Tools**](/ai/agent/custom-tools) - Connect the AI to your own APIs for real-time data lookups
* [**Knowledge Base**](/ai/agent/training) - Train the AI with FAQs and documents
* [**Personalization**](/ai/agent/personalization) - Define the AI's role and escalation behavior
# Connectors
Source: https://docs.periskope.app/ai/agent/connectors
Connect your AI Agent to your own systems over MCP so it can look things up and take actions
Connectors let the AI Agent work with systems that speak [MCP](https://modelcontextprotocol.io) (Model Context Protocol) — your product docs, CRM, order system, or any other MCP server. The AI reads from the connected system in real time and, if you allow it, takes actions there too.
Access Connectors through **AI** > **Tools**, on the **Connectors** tab.
Connectors require a Pro plan, and the AI Agent must be enabled before you can add one.
## Add a Connector
Click **Add connector** and provide:
* **Name**: A label to identify the connector (e.g. "Company Docs")
* **MCP server URL**: The MCP server's endpoint (e.g. `https://docs.company.com/mcp`). It must be a public `https` address — private and local addresses are rejected.
* **Authentication**: How Periskope signs in to the server
| Type | Use For |
| - | - |
| **None** | Public servers with no credentials required |
| **Bearer** | A single bearer token sent as `Authorization: Bearer ` |
| **Header** | A custom header key/value pair (e.g. `X-Api-Key`) |
| **OAuth** | Sign in through the provider — you're redirected to authorize and returned automatically |
You can connect up to 5 connectors per organization.
## Lookups and Actions
Once connected, Periskope discovers the tools the server offers and sorts them into two groups. Expand a connector to see them and switch individual tools on or off.
| Group | What it does | Default |
| - | - | - |
| **Lookups** | Read information. They never change anything in your system. | Switched on when you connect |
| **Actions** | Create or change data in your system. | Every one stays off until you turn it on |
A connector can have up to 100 tools switched on.
Periskope uses the read-only marking the server publishes for each tool. If a server doesn't publish one, Periskope goes by the tool's name — names that start with a reading word such as `search`, `get`, `list`, `read` or `fetch` count as Lookups.
Look through the **Lookups** list too. For a server that doesn't label its tools, a tool that both reads and writes (for example `get_or_create_customer`) can appear as a Lookup. Switch off anything you don't want the AI to run on its own.
## How the AI Uses Actions
* The AI can only call tools you've switched on, and only when the conversation calls for it.
* The AI never repeats the same action with the same details in a conversation, so a customer's request isn't carried out twice.
* If a connector doesn't confirm an action in time (calls time out after 10 seconds), the AI doesn't try again. It tells the customer your team will confirm. Check the connected system to see whether the action went through.
* If an action returns an error, the AI reads it and can correct the details and try once more.
* Anything a connector returns is treated as information, never as instructions the AI must follow.
You can see every tool call in a conversation in the [Logs](/ai/agent/logs) view under **Tool Calls**.
## Manage a Connector
* **Refresh** re-syncs the tool list after the server's capabilities change. Your on/off choices for existing tools are kept.
* **Disconnect** removes the connector entirely.
* If a connection using OAuth expires or is revoked, the connector is marked **Needs re-auth**. Click **Reconnect** to sign in again.
## Next Steps
* [**Custom Tools**](/ai/agent/custom-tools) - Connect the AI to your own HTTP APIs
* [**Built-in Tools**](/ai/agent/built-in-tools) - Configure native AI actions like creating tickets and private notes
* [**Knowledge Base**](/ai/agent/training) - Train the AI with FAQs and documents
# Custom Tools
Source: https://docs.periskope.app/ai/agent/custom-tools
Connect your AI Agent to your own APIs so it can fetch real-time data and take actions in external systems
Custom Tools let you connect the AI Agent to any external HTTP API. When a customer asks something that requires live data — like checking an order status, fetching account details, or querying your internal systems — the AI can call your API and use the response to answer accurately.
Access Custom Tools through **AI** > **Tools**, on the **Custom Tools** tab.
The AI decides which tool to call based on the **tool name** and **description** you provide. Each tool can be toggled active or inactive individually.\\
***
## Creating a Custom Tool
Click **+ New Tool** to open the tool editor. A custom tool has four sections:
1. Basic Information
2. Authentication
3. Request Headers
4. Parameters
5. Response Schema (optional)
### 1. Basic Information
**Tool Name** (required)
Use `snake_case` with no spaces. The AI sees this name when deciding which tool to call.
```text theme={null}
get_order_status
fetch_account_details
check_subscription_plan
```
**Description** (required)
Describe exactly what this tool does and when the AI should use it. Be specific — the AI uses this description to decide whether to call this tool.
```text theme={null}
Fetch the current status of a customer order. Use this when the customer
asks about their order delivery, shipment tracking, or order confirmation.
```
**HTTP Method**
Select `GET` or `POST`.
* Use `GET` for fetching data (parameters go in the query string)
* Use `POST` for sending data (parameters go in the request body)
**Endpoint URL**
The full URL the AI will call. Must be a publicly accessible HTTPS endpoint.
***
### 2. Authentication
Choose how the AI authenticates with your endpoint:
| Auth Type | How It Works |
| - | - |
| **No Auth** | Public endpoints that require no authentication |
| **Bearer Token** | Sends an `Authorization: Bearer ` header |
| **API Key** | Sends a custom header with a key-value pair |
| **Basic Auth** | Encodes username and password as a Base64 header |
For **Bearer Token**, enter your token and it will be sent as `Authorization: Bearer ` with every request.
***
### 3. Request Headers
Static headers sent with every call to this endpoint. Authentication headers are managed separately in the Authentication section above.
Use this for headers like `org_id`, `Content-Type`, or any other static values your API requires.
Click **+ Add Header** to add name-value pairs.
***
### 4. Parameters
Parameters define the inputs the AI will provide when calling this tool. Each parameter has:
| Field | Description |
| - | - |
| **Name** | The parameter name (use `snake_case`) |
| **Type** | Data type: `String`, `Number`, `Boolean`, etc. |
| **Location** | Where the parameter is sent: `Body`, `Query`, or `Path` |
| **Required** | Whether the AI must have this value before calling the tool |
| **Description** | Tell the AI what this parameter is and how to get it |
**Available Contexts**
At the bottom of the parameters section, you'll see **Available contexts**: `+ chat_id`, `+ org_phone`, `+ chat_name`. Click these to automatically inject conversation context as parameter values — no need for the AI to ask the customer.
**Parameter Description Tips**
The description tells the AI where to get the value from. Be explicit:
```text theme={null}
the org_id of the customer. AI needs to ask for the org_id or use the
get_chat_details tool to find it.
```
```text theme={null}
The customer's order number. Ask the customer for this if not already
provided in the conversation.
```
***
### 5. Response Schema (Optional)
Optionally describe the shape of your API's response using JSON Schema. This helps the AI accurately interpret the response and extract the right information.
Enable the toggle and provide your schema:
```json theme={null}
{
"type": "object",
"properties": {
"order_status": {
"type": "string",
"description": "Current status of the order: pending, shipped, delivered, or cancelled"
},
"estimated_delivery": {
"type": "string",
"description": "Estimated delivery date in ISO 8601 format"
},
"tracking_url": {
"type": "string",
"description": "URL for the customer to track their shipment"
}
}
}
```
Click **Insert example** to auto-generate a schema structure you can edit.
Adding a response schema significantly improves how accurately the AI interprets API responses, especially for complex or nested JSON structures. Always add descriptions to each property so the AI understands what the field means.
***
## Example: Full Custom Tool Setup
Here's a complete example of a tool that fetches broadcast status for a customer:
**Basic Information**
```text theme={null}
Name: get_broadcast_details
Description: Fetch the status of any broadcast for a client. Useful when the
client is asking about updates on their bulk message, failure reasons of
broadcasts, and delivery issues with broadcasts.
HTTP Method: POST
Endpoint: https://api.yourcompany.com/tools/get_broadcast_details
```
**Authentication**: Bearer Token
**Parameters**:
* `customer_org_id` — String, Body, Required — "The org\_id of the customer. AI needs to ask for the org\_id or use get\_chat\_details tool to find it"
* `customer_broadcast_id` — String, Body, Required — "The broadcast\_id. AI needs to ask for the broadcast\_id in order to fetch its details"
***
## Managing Tools
Back on the Custom Tools list, you can:
* **Toggle active/inactive**: Enable or disable a tool without deleting it. Inactive tools are not called by the AI.
* **Edit**: Click the pencil icon to modify a tool's configuration
* **Delete**: Click the trash icon to permanently remove a tool
The AI only calls tools that are marked as **Active**. Use the inactive state when testing new tools or temporarily disabling one without losing its configuration.
## How the AI Uses Custom Tools
The AI decides when to call a custom tool based on the conversation context and the tool's description. When it determines a tool is relevant:
1. It gathers the required parameters — either from the conversation context, by asking the customer, or from other tools
2. It makes the API call
3. It uses the response to formulate an accurate answer
You can see all tool calls made in a session in the [Logs](/ai/agent/logs) view under **Tool Calls**.
## Next Steps
* [**Built-in Tools**](/ai/agent/built-in-tools) - Configure native AI actions like creating tickets and private notes
* [**Knowledge Base**](/ai/agent/training) - Train the AI with FAQs and documents
* [**Personalization**](/ai/agent/personalization) - Define the AI's role and how it uses tools
# AI Agent Overview
Source: https://docs.periskope.app/ai/agent/overview
Introduction to Periskope's AI Agent - what it is, how it works, and how to enable it
## What is AI Agent?
If you receive repetitive questions from clients and would like to manage day-to-day conversations automatically, Periskope's AI Agent can handle it for you. Train this AI to answer important questions on your behalf, escalate issues to the right team members, and create tickets for important tasks intelligently.
## How to Enable the AI Agent
Everything starts on the **Overview** page — go to **AI** > **Overview**.
If required setup is missing, the Overview page shows a **Setup** checklist with the steps still open:
* **Set the agent's role and instructions** (required) — takes you to Personalization
* **Set its identity and personality** (required) — takes you to Personalization
* **Add answers it can use** (optional) — takes you to the Knowledge Base
The agent cannot be turned on until both required steps are done.
Toggle **AI Agent** at the top of the Overview page. When active, the AI Agent starts responding to messages based on your configured activation criteria.
The **Configuration** cards below the status card are the five things that shape how the agent behaves. Select a card to configure it — see the table below.
## The Five Configuration Areas
| Card | What it controls |
| - | - |
| [**Activation**](/ai/agent/settings) | When the agent responds — activation mode, response delay, allowed numbers, operating hours |
| [**Personalization**](/ai/agent/personalization) | Who the agent is — its name, your business context, its tone, and topics to avoid |
| [**Knowledge Base**](/ai/agent/training) | What it answers from — FAQs, documents, external sources, self-learned answers |
| [**Tools**](/ai/agent/built-in-tools) | What it can do beyond replying — send messages, create tickets and notes, call your own APIs |
| [**Flagging**](/ai/flagging) | When a conversation needs a person — flagging rules and when flags are cleared |
When self-learned answers are waiting on you, the Knowledge Base card shows a **need review** badge with a **Review** shortcut.
## Where Everything Lives
The AI section of the sidebar is grouped into three parts:
| Group | Pages |
| - | - |
| **AI Agent** | Overview, Activation, Personalization, Knowledge Base, Tools |
| **Monitor** | Credit Usage, Self-Training, Analytics, Logs |
| **General** | Flagging, Internal Contacts |
## How the AI Decides When to Respond
The AI Agent activates in a conversation when a message meets the **Activation Criteria** configured on the Activation page. The system uses intelligent prompt-based activation rather than simple keyword matching.
### Activation Process
1. **Base Activation Rules**: The system evaluates if a message meets core criteria such as:
* Contains a question, complaint, technical problem, or concern
* Requests an action, assistance, or support
* Appears to be something that requires business attention
2. **Custom Activation Rules**: Additional rules you define to customize when the AI should or should not respond
3. **Internal Contact Filtering**: Messages from contacts marked as "internal" are automatically excluded from AI responses
Once activated, the AI will respond after a configurable delay using your Knowledge Base, Personalization settings, and available tools. If it doesn't have a suitable response, it will follow the escalation rules you've configured.
### AI Agent States
The AI Agent operates in four distinct states:
* **INACTIVE**: AI Agent is enabled and monitoring conversations, waiting for messages that meet activation criteria
* **ACTIVE**: AI Agent is actively listening and will respond to the next external message
* **THINKING**: AI Agent is actively processing a message and preparing to respond
* **SNOOZED**: Temporarily inactive after human intervention, will reactivate after the snooze duration
## How to Stop the AI from Responding
When the AI Agent is active or thinking, you will see the **AI button** in the chat box along with a status indicator.
**Taking Over from AI**
Click the **AI button** to take over the conversation:
* **If AI is in THINKING state**: AI immediately enters **SNOOZED** state for the configured snooze duration. It will not respond during this period and then returns to INACTIVE.
* **If AI is in ACTIVE state**: AI immediately enters **INACTIVE** state. It will resume listening for messages that meet the activation criteria.
* **If an internal team member replies**: Always triggers SNOOZED state, using the same snooze duration setting.
The AI also automatically enters **SNOOZED** state when an **internal** team member responds to the conversation.
## AI Agent Decision Workflow
For every incoming message, the AI Agent follows this decision process:
1. **Message arrives** in a conversation
2. **Internal Contact Check**: If the sender is an internal team member → skip AI processing entirely
3. **AI Agent Status Check**: If AI is disabled for this chat → no response
4. **Activation Criteria Analysis**: AI evaluates the message against the activation prompt
5. **Response Delay**: Wait for the configured delay period (giving human agents time to respond first)
6. **Knowledge Base Search**: AI searches FAQs, Documents, and Self-Learned context
7. **Tool Calls**: AI calls any relevant built-in or custom tools to gather information
8. **Response Generation**: AI crafts a response based on all available context and your Personalization settings
9. **Action**: AI sends a direct reply, creates a private note, creates a ticket, or escalates to a team member
10. **State Management**: AI returns to ACTIVE state and continues monitoring the conversation
## Next Steps
* [**Activation**](/ai/agent/settings) - Configure activation rules, response delays, and operating hours
* [**Personalization**](/ai/agent/personalization) - Define the AI's name, role, personality, and behavior
* [**Knowledge Base**](/ai/agent/training) - Train the AI with FAQs, documents, and self-learned context
* [**Built-in Tools**](/ai/agent/built-in-tools) - Configure what actions the AI can take
* [**Custom Tools**](/ai/agent/custom-tools) - Connect the AI to your own APIs
# Personalization
Source: https://docs.periskope.app/ai/agent/personalization
Define your AI Agent's identity, role, instructions, and personality
The Personalization page is where you shape how your AI Agent thinks, communicates, and behaves. Access it through **AI** > **Personalization**.
This page has four key sections:
1. **Identity** — The AI Nickname customers see in conversations
2. **Personality Type** — Choose the AI's communication style and tone
3. **Agent Role and Instructions** — Tell the AI who it is and how it should operate
4. **Restrictions** — Set hard limits on what the AI cannot do
Changes are staged: a save bar at the bottom shows how many unsaved changes you have. Click **Save changes** to apply them, or **Discard** to revert.
***
## Identity
**AI Nickname**
The name the AI uses to identify itself in customer conversations — for example, `Periskope AI` or `Support Bot`. This is shown to customers so they know they are interacting with an AI.
***
## Agent Role and Instructions
This is the most important field for configuring your AI Agent. Use it to give the AI a clear understanding of your company, its role, and how to respond to customers.
Click **Use template** to start from a structured, ready-made prompt and fill in the placeholders for your business, rather than writing one from scratch.
Think of this as the AI's system prompt. The more context you provide, the better the AI will perform. Cover:
* **Who the AI is**: its name, role, and relationship to your team
* **What your company does**: a clear description of your product or service
* **How it should communicate**: tone, style, escalation behavior
* **Team structure**: who handles what, so the AI can delegate correctly
### Example Configuration
```
Role & Identity
You are Periskope AI, a sales and customer support assistant for [Company Name].
You handle customer conversations across sales, support, onboarding, and operations.
You work closely with the internal team to ensure customers receive accurate,
timely support.
Communication Guidelines
- You are warm, polite, patient, and solution-oriented.
- You only provide information based on the knowledge base and context given to you.
- If you don't have the required information, inform the customer once and stay
silent on that topic unless they ask something different.
- You never guess, hallucinate, or fabricate information.
Internal Coordination
- Use Private Notes for low-priority internal communication or FYIs.
- Use Tickets for high-priority issues, bugs, or customer-blocking problems.
- When a ticket or note is created, inform the customer professionally without
disclosing internal email addresses or personal identifiers.
About [Company Name]
[Company Name] is a platform that helps businesses [primary value proposition].
Core capabilities:
- [Capability 1]
- [Capability 2]
- [Capability 3]
Team Structure
Engineering Team
- [Name] — owns [feature areas]
- [Name] — owns [feature areas]
Sales Team
- [Name] — handles pricing, plans, demos, contracts
Route: Technical bugs → Engineering | Pricing/demos → Sales
Operational Rules
- Never expose internal processes or personal details to customers.
- Never promise timelines unless explicitly provided.
- Always prefer clarity and minimalism in responses.
```
The Agent Role and Instructions field is a system prompt — treat it like prompt engineering. Be specific and structured. Vague instructions produce vague results. Read the [Prompt Engineering Guide](https://www.promptingguide.ai/introduction/tips) for best practices.
***
## Restrictions
Use this field to set hard limits — things the AI should **never** do, regardless of what a customer asks.
**Common examples:**
```
- You cannot schedule calls yourself. Always inform a sales agent to follow up.
- You cannot process refunds. Direct customers to billing@company.com.
- Do not share pricing discounts. Route to the sales team.
- Never confirm specific delivery dates unless provided in the knowledge base.
```
Keep restrictions focused and specific. Overly broad restrictions can prevent the AI from being helpful.
***
## Personality Type
Choose a pre-configured personality that sets the AI's communication style, tone, and response behavior:
| Personality | Style | Best For |
| - | - | - |
| **Friendly** | Warm, conversational, moderate detail | General support, onboarding |
| **Strict Grounded** | Fact-based only, no assumptions | Technical or compliance-heavy contexts |
| **Spartan** | Ultra-brief, authoritative, zero fluff | High-volume support where speed matters |
| **Sales Forward** | Confident, value-driven, conversion-focused | Sales conversations and demos |
Each personality defines:
* **Tone Style**: The communication register (e.g., warm and polite, authoritative)
* **Response Length**: How detailed responses should be (concise, moderate, detailed)
* **Unknown Info Handling**: What to do when information isn't available
* **Restrictions**: Built-in behavioral guardrails (e.g., no fabricating info, no excessive apologizing)
***
## Next Steps
* **[Knowledge Base](/ai/agent/training)** - Train the AI with FAQs, documents, and self-learned context
* **[Tools](/ai/agent/built-in-tools)** - Configure what actions the AI can take
* **[Custom Tools](/ai/agent/custom-tools)** - Connect the AI to your own APIs
# Self-Training
Source: https://docs.periskope.app/ai/agent/self-training
Let the AI learn from your team's resolved chats every week, and review or re-run its training
Self-Training is a scheduled process that reviews your team's resolved conversations and drafts new Knowledge Base entries from them — so the AI keeps improving without anyone manually writing FAQs. Access it through **AI** > **Self-Training**.
Self-Training is what powers the **Self-Learned** tab in the [Knowledge Base](/ai/agent/training#self-learned-context). This page controls the schedule, settings, and run history; the drafted entries themselves are reviewed inside the Knowledge Base.
## How It Works
When the **Self-Training** toggle is on, every **Sunday** the AI:
1. Reviews your team's resolved chats from the past week
2. Extracts the answers your team provided to customers
3. Drafts FAQ entries for your Knowledge Base from those answers
Nothing is published automatically — every new entry waits for review before it's used to answer customers, unless you've set entries to auto-activate (see below).
## Self-Learned Knowledge Settings
Under **Self Learned Context Requires Review**, choose how drafted FAQs behave once the AI creates them:
| Option | Behavior |
| - | - |
| **Auto-activate** | FAQs the AI learns are activated immediately and used for future responses |
| **Require manual review** | FAQs the AI learns stay inactive until you review and approve them in the Knowledge Base |
This is the same setting described in [Self-Learned Context](/ai/agent/training#self-learned-context) — changing it here or in the Knowledge Base has the same effect.
The **Drafted FAQs** card shows how many entries are currently pending review, with a **View self-learned FAQs** shortcut straight to the filtered Knowledge Base list.
## Training Runs
The **Training runs** table is a history of every weekly run, plus any you've triggered manually:
| Column | Meaning |
| - | - |
| **Week** | The 7-day period the run processed |
| **Status** | Queued, In progress, Dispatched, Failed, or Complete |
| **FAQs learned** | New FAQs created and existing ones updated, once the run completes |
| **Trigger** | Scheduled (automatic Sunday run) or Manual |
| **Last run** | When the run was last dispatched or performed |
If a run fails, hover the status to see the error.
### Running Training Manually
Click **Run training** to process a specific week on demand — useful if you want fresh FAQs sooner than the next scheduled Sunday, or want to re-process a past week.
Pick the start date of the week you want processed (the AI trains on the 7-day window starting from that date) and submit. The **Run training** button is only enabled when Self-Training is turned on. If that week is already running, you'll be notified rather than starting a duplicate.
## Next Steps
* [**Knowledge Base**](/ai/agent/training) - Review, approve, and edit the FAQs Self-Training drafts
* [**Org Assistant**](/ai/agent/ai-assistant#keep-the-knowledge-base-up-to-date) - Ask the AI to audit your Knowledge Base for gaps, duplicates, and outdated entries
# Activation
Source: https://docs.periskope.app/ai/agent/settings
Configure when your AI Agent responds, how long it waits, and the hours it operates in
The Activation page controls **when** the AI Agent responds. Access it through **AI** > **Activation**.
Turning the agent on or off is done from the [**Overview**](/ai/agent/overview) page, not here. The AI's name and personality live on [**Personalization**](/ai/agent/personalization).
Changes on this page are staged. A save bar appears at the bottom showing how many unsaved changes you have — click **Save changes** to apply them, or **Discard** to revert.
## Customize Activation Rules
Fine-tune which messages should trigger the AI. Click **Activation prompt** to open the editor, which has two parts:
* **Base Activation Rules (Read-only)** — the built-in criteria the AI always evaluates:
* Messages that raise an issue, complaint, technical problem, or concern
* Messages that request an action, assistance, or support
* Messages that appear to require business attention
* **Custom Activation Rules** — your own additions, for example:
* "Do NOT activate if it's just a greeting without a question"
* "Do NOT activate if the message is a simple acknowledgment like 'Ok', 'Thanks', 'Got it'"
* "Activate if the customer mentions a specific product by name"
Custom rules are **additive** — they extend the base rules rather than replace them.
## Chat Activation Mode
Controls whether the AI is on or off by default across your chats:
| Mode | Behavior |
| - | - |
| **Auto-activate for all chats** | AI is ON for all conversations. You can manually disable it per chat. |
| **Manual activation per chat** | AI is OFF by default. You enable it only for specific chats where you want responses. |
Start with **Manual activation** while you're testing, then switch to **Auto-activate** once you're confident in your configuration.
### AI Settings in a Chat
When you open the **Settings tab** of a chat, you'll find two AI-specific toggles that control how the AI behaves in that particular conversation.
#### Allow AI Flagging
When enabled, the AI will automatically flag important or sensitive messages in this chat for your team's attention — so nothing critical gets missed in a busy conversation.
#### Allow AI Agent
When enabled, the AI Agent is active in this chat and can respond to customer messages automatically, based on your knowledge base and configured tools. Turn this off if you want a team member to handle the conversation manually.
> **Note:** These toggles are per-chat settings. Turning off Allow AI Agent in one chat does not affect other chats where it is enabled.
## Operational Settings
### Allowed Phone Numbers
Restrict which phone numbers the AI Agent is active on. When set, the AI will only respond on conversations coming from or going to the listed numbers. Leave empty to allow all numbers.
### Response Delay
How long the AI waits after activation criteria is met before actually sending a response.
* **Default**: 3 seconds
* **Range**: 3–6000 seconds
* This gives your human agents a window to respond first. If a human replies within the delay window, the AI will stand down.
### Snooze Duration
How long the AI stays inactive after a human agent has responded or manually snoozed it.
* **Default**: 30 seconds
* **Range**: 0–6000 seconds
* During the snooze period, the AI will not respond to any new messages, allowing the human agent to fully handle the conversation.
* After the snooze period, the AI automatically returns to INACTIVE state and resumes monitoring for activation criteria.
### Operating Hours
Define specific hours and a timezone when the AI should be active. Outside these hours, the AI will not respond automatically, even if activation criteria are met. Useful if you only want AI coverage during office hours, off-hours, or weekends.
## Internal Contacts
The AI Agent automatically skips messages from contacts marked as internal team members. This ensures the AI only handles external customer conversations and never interferes with internal communications.
Go to **AI** > **Internal Contacts** to view, add, or remove contacts from the internal list. You can search by name or phone number.
When an internal contact replies in a conversation, the AI Agent is automatically snoozed for the configured snooze duration.
## Next Steps
* **[Personalization](/ai/agent/personalization)** - Define the AI's name, role, instructions, and personality
* **[Knowledge Base](/ai/agent/training)** - Train the AI with FAQs, documents, and self-learned context
* **[Built-in Tools](/ai/agent/built-in-tools)** - Configure what actions the AI can take
* **[Custom Tools](/ai/agent/custom-tools)** - Connect the AI to your own APIs
# Knowledge Base
Source: https://docs.periskope.app/ai/agent/training
Train your AI Agent with FAQs, documents, and self-learned context for accurate, reliable responses
The Knowledge Base is where you teach your AI Agent what to know and how to answer customer questions. Access it through **AI** > **Knowledge Base**.
Every entry — FAQs, self-learned Q\&A pairs, and documents — lives in one list. Use the tabs above the list to filter by type:
| Tab | Shows |
| - | - |
| **All** | Everything in the knowledge base |
| **FAQ** | Entries you wrote manually |
| **Self-Learned** | Q\&A pairs the AI discovered automatically from real conversations |
| **Documents** | Uploaded PDF reference material |
Next to the search bar, a second row of filters — **All**, **Active**, **Inactive**, **Needs Review** — narrows the list by status, with a live count next to each. **Needs Review** is where self-learned entries land while they're waiting for approval.
Use **Add New** to create a **FAQ** or upload a **Document (PDF)**. To have the AI read from a live system instead, see [Connectors](/ai/agent/connectors). Select one or more entries to reveal a bulk action bar for activating, deactivating, or deleting them at once.
The **AI Training** button opens a small settings panel with two switches:
| Setting | What it controls |
| - | - |
| **AI Training** | Whether the AI auto-learns from team responses in conversations (the weekly [Self-Training](/ai/agent/self-training) run) |
| **Require Approval** | Whether self-learned entries need review before the AI can use them |
***
## FAQs
FAQs are essentially **prompts for the AI Agent**. Click **Add New** > **FAQ** (or open an existing entry) to get the full-page editor. Each FAQ entry has three fields:
* **Question**: The customer query — add multiple variations so the AI can match different phrasings
* **Answer**: The response the AI should provide, with an optional file/link attachment
* **Instructions**: Special behavioral guidance for this specific FAQ (optional)
The editor also shows the entry's status (Active/Inactive/Needs Review) with a switch to toggle it, and prev/next arrows to move through the rest of the list without going back to the Knowledge Base page.
### Writing Effective Questions
Add multiple variations of the same question so the AI can identify it regardless of how customers phrase it:
```text theme={null}
How much does your service cost?
What are your pricing plans?
Can you tell me about your subscription fees?
How much does it cost per month?
```
The more variations you add, the more reliably the AI will match incoming questions to the right FAQ entry.
### Writing Effective Answers
Keep answers concise but complete. Use bullet points for multi-step or multi-item responses. Include links where relevant.
```text theme={null}
Our service has three tiers:
- Basic: $10/month — includes core features
- Pro: $25/month — includes advanced analytics and integrations
- Enterprise: Custom pricing — contact sales@company.com
```
### Using Instructions for Controlled Responses
The **Instructions** field lets you add behavioral rules specific to this FAQ — without affecting the rest of the AI's behavior.
**Basic instructions:**
```text theme={null}
Ask for the user's account email before providing specific account details.
```
**Conditional instructions:**
```text theme={null}
If the user mentions an error code, ask for a screenshot before troubleshooting.
If the user asks about pricing, confirm their region first.
```
**Multi-turn / escalation instructions:**
```text theme={null}
If they are facing issues adding a new user and appear to have hit their user limit,
explain that they may need to upgrade their plan. Ask if that's the case, and if so,
direct them to Settings > Manage Plans or notify the sales team to step in.
```
FAQs are evaluated as prompts by the AI model. Writing clear, specific instructions produces far better results than vague guidance. If an FAQ isn't working as expected, try being more explicit in the Instructions field.
### FAQ Best Practices
* **Include multiple question variations** — different phrasings, abbreviations, and common misspellings
* **Keep answers factual** — the AI will not fabricate information, but vague answers lead to vague responses
* **Use instructions for edge cases** — handle follow-up logic, escalations, and conditional behavior here
* **Review regularly** — add new FAQs for recurring questions you see in conversations
***
## Documents
Documents let you upload large bodies of reference content that the AI searches when answering questions. This is ideal for:
* Product documentation
* Company policies and procedures
* Pricing sheets
* Onboarding guides
* Technical specifications
### Recommended Document Formats
**1. Q\&A Format (Most Effective)**
Structure content as question-answer pairs. This directly mirrors how the AI processes queries and produces the most reliable results.
```text theme={null}
Q: How do I reset my password?
Ans: Go to the login page and click "Forgot Password". Enter your email address
and you'll receive a reset link within 5 minutes.
Q: What payment methods do you accept?
Ans: We accept Visa, Mastercard, American Express, PayPal, and bank transfers
for enterprise accounts.
```
**2. Paragraph Structure**
Group related information into focused paragraphs with clear headings:
```text theme={null}
[Product Features]
Our platform includes real-time analytics, custom reporting, and team
collaboration tools. All features are accessible from the dashboard.
[Security]
We implement industry-standard encryption for all data. Servers are hosted
in ISO-certified data centers with 24/7 monitoring and SOC 2 compliance.
```
**3. List Structure**
Use bullet points for step-by-step instructions or feature lists:
```text theme={null}
[Getting Started]
- Sign up with your email address
- Verify your email through the confirmation link
- Complete your profile setup
- Connect your first integration
- Invite team members
```
The AI searches documents for relevant sections when answering questions. Well-structured documents with clear headings and labeled sections produce better results than unformatted walls of text.
***
## Self-Learned Context
The AI Agent automatically learns from real conversations. Every Sunday, [Self-Training](/ai/agent/self-training) reviews your team's resolved chats from the past week, extracts the answers they gave, and drafts new FAQ entries here — you can also trigger a run manually for any week from the Self-Training page. Filter the Knowledge Base list to the **Self-Learned** tab to see only these entries.
This means your knowledge base improves over time without manual effort — every good answer your team gives becomes training data.
### Require Approval
Open the **AI Training** panel above the list and toggle **Require Approval** to control what happens to newly self-learned entries:
| Require Approval | Behavior |
| - | - |
| **On** | New self-learned Q\&A pairs are held out with a **Needs Review** status until you approve them — they aren't used by the AI yet |
| **Off** | New self-learned Q\&A pairs go **Active** immediately and are used by the AI right away |
Turning it on is recommended when:
* You want tight quality control over what the AI learns
* Your team's responses may include information not appropriate for all customers
* You're in an early stage of AI deployment
Turning it off suits mature deployments where your team consistently gives accurate, appropriate answers.
To review pending items, filter the list to **Needs Review**, open an entry, and use its status switch to approve (activate) or leave it inactive. You can also select multiple entries and use the bulk **Activate**/**Deactivate**/**Delete** actions.
***
## Knowledge Base Optimization Tips
**Quality over quantity.** Start with a small set of high-quality FAQs covering your most common questions. A well-written FAQ with good instructions outperforms ten vague ones.
**Test with real questions.** After adding FAQs, test them by sending actual customer questions through the AI and reviewing the responses in [Logs](/ai/agent/logs).
**Fill gaps over time.** Monitor AI conversations to identify questions the AI is handling poorly or escalating too often. Add or refine FAQs for those topics.
**Avoid conflicting content.** If multiple FAQ entries or documents cover the same topic with different answers, the AI may give inconsistent responses. Keep your knowledge base clean.
**Review self-learned entries regularly.** Self-learned context is valuable but requires curation. Schedule a regular review of pending entries to keep your knowledge base growing accurately.
**Let the Org Assistant do the audit.** Instead of scanning entries manually, open the [Org Assistant](/ai/agent/ai-assistant#keep-the-knowledge-base-up-to-date) on this page and ask it to find gaps, flag outdated articles, or spot duplicates — it searches your actual FAQs, documents, and self-learned entries and reports back.
## Next Steps
* [**Personalization**](/ai/agent/personalization) - Define the AI's role, personality, and instructions
* [**Built-in Tools**](/ai/agent/built-in-tools) - Configure what actions the AI can take
* [**Custom Tools**](/ai/agent/custom-tools) - Connect the AI to your own APIs
# Flag Messages with AI
Source: https://docs.periskope.app/ai/flagging
Guide to automatically flag important messages with Periskope AI
## Overview
AI Message Flagging helps you identify and track important customer queries for response time measurement and team productivity analysis. This feature is separate from the AI Agent and focuses on message categorization and response time tracking.
If you miss important customer queries or requests often, AI flagged messages is for you. You can now view AI flagged messages, reply or create a ticket to unflag them and automatically measure first response times.
**AI Flagging vs AI Agent**: AI Flagging categorizes messages for tracking purposes, while the AI Agent automatically responds to customers. These are independent features that can be used together or separately.
## How are messages flagged by AI
For any incoming message, Periskope AI checks if -
1. the message is by someone external - you can mark contacts as "internal" from the contacts tab
2. the message is a question, query or request for support - Periskope uses Google Vertex under the hood to seperate queries from simple statements
If both the above conditions are true, the message is flagged by AI
## How to unflag messages by AI
There are 3 ways to unflag an AI flagged message -
1. Replying to the message - when a user replies to the message via Periskope or a contact marked as "internal" replies to the message via WhatsApp, the message is automatically unflagged
2. Creating a ticket - when you right click and create a ticket out of a flagged message, the message is automatically unflagged
3. Manual unflagging - you can simply right click on the message and choose "unflag" to manually unflag a message
## How are response times calculated
When a user replies to a flagged message via Periskope, the first response time (FRT) is calculated as the time between the incoming flagged message and the user reply. FRT is not calculated when a user replies directly from WhatsApp.
## Customizing Flagging Criteria
You can customize which messages get flagged from **AI** > **Flagging**. Turn the feature on with **Enable AI Flagging**, then fine-tune the AI's message categorization to match your business needs. Changes are staged — click **Save changes** in the save bar to apply them.
### Flagging Prompt Components
**Base Prompt**
* Default criteria for identifying important messages
* Looks for questions, issues, requests, and business-relevant content
* Provides consistent baseline for message evaluation
**Custom Prompt**
* Add specific rules for your business context
* Define industry-specific terms or scenarios
* Exclude certain types of messages from flagging
* Fine-tune sensitivity for your customer communication patterns
**Example Custom Flagging Rules:**
```text theme={null}
Only flag queries about medicine and medical terms. For example: "How many times do I take this medicine per day?" Don't flag normal questions.
```
This example shows how you can create very specific flagging criteria that only capture messages relevant to your particular business domain.
AI does not flag messages sent by contacts marked as internal. Use **Manage Internal Contacts** on the Flagging page to maintain that list.
## Unflagging Mode
Under **Unflagging Mode**, choose how your team's replies clear flags in a chat:
| Mode | Behavior |
| - | - |
| **Unflag all flagged messages on reply** | Any reply from your team in a chat unflags every flagged message in that conversation. |
| **Unflag only the flagged message that was replied to** | A flagged message is unflagged only when a team member replies to it directly. Other flagged messages in the chat keep their flags. |
# Periskope Whatsapp MCP
Source: https://docs.periskope.app/ai/mcp
Connect your AI assistant to WhatsApp in seconds using Periskope's hosted MCP server
### What is MCP (Model Context Protocol)
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is a standardized interface that allows AI models like Claude and GPT to interact with external services and tools. It provides a structured way for AI assistants to execute actions, access data, and control applications through predefined functions and commands. In the context of Periskope WhatsApp, MCP enables AI assistants to directly **manage WhatsApp conversations, send messages, handle contacts, and perform other WhatsApp-related operations** programmatically.
## Setup
1. Sign up for an account at [console.periskope.app](https://console.periskope.app)
2. You will need a phone number that you will use to manage all your WhatsApp chats, groups and communities logged in on WhatsApp.
3. Open Settings on your WhatsApp App and click on **Link device**
4. Now scan the QR code shown on Periskope screen
If you face any errors, click on **refetch QR** to fetch a new QR code.
Paste the following URL into your AI client's MCP server configuration:
```
https://api.periskope.app/mcp
```
1. Open Claude Desktop and go to **Customize**
2. Navigate to **Connectors** → **Add custom connector**
3. Paste `https://api.periskope.app/mcp` as the server URL
4. Click **Add**
1. Open ChatGPT and go to **Settings**
2. Navigate to **Apps** → **Add Advanced Settings** → **Turn on Developer mode** → **Create app**
3. Paste `https://api.periskope.app/mcp` as the server URL
4. Click **Connect**
Add the following to your `mcp.json` configuration file:
```json theme={null}
{
"mcpServers": {
"periskope": {
"url": "https://api.periskope.app/mcp"
}
}
}
```
After adding the MCP server URL, your client will open the Periskope authorization page.
1. **Select your organization** from the list
2. **Choose the WhatsApp phone(s)** you want to grant access to
3. Click **Authorize**
You'll be redirected back to your AI client — fully connected and ready to use.
## Available Tools
The MCP provides several tools for interacting with Periskope's WhatsApp API:
### Chat Management
* **periskope\_list\_chats**: Lists all WhatsApp chats
* **periskope\_get\_chat**: Gets details about a specific WhatsApp chat
* **periskope\_create\_chat**: Creates a new WhatsApp group chat
* **periskope\_update\_chat\_labels**: Updates the labels of a WhatsApp chat
* **periskope\_update\_chat**: Updates a WhatsApp chat properties on Periskope
* **periskope\_update\_chat\_settings**: Updates the settings of a WhatsApp chat
* **periskope\_search\_chat**: Searches for chats by name
* **periskope\_list\_all\_messages**: Lists all messages across all chats globally
* **periskope\_list\_all\_notifications**: Lists all notifications across all chats globally
* **periskope\_get\_chat\_notifications**: Gets notifications for a specific chat
* **periskope\_get\_chat\_notes**: Gets all private notes in a specific chat
### Message Management
* **periskope\_send\_message**: Sends a WhatsApp message (text, media, or poll) to a specified chat
* **periskope\_list\_messages\_in\_a\_chat**: Lists all messages in a specific WhatsApp chat
* **periskope\_list\_messages\_in\_a\_chat\_by\_id**: Gets a message by its ID
* **periskope\_get\_media**: Downloads a message's attachment (image, document, audio, video) and returns it inline so the AI can view or read it — media URLs in message results are private links the AI cannot open on its own
* **periskope\_get\_message\_status**: Gets the delivery status of a message
* **periskope\_react\_to\_message**: Reacts to a message
* **periskope\_forward\_message**: Forwards a message to other chats
* **periskope\_broadcast\_message**: Broadcasts a message to multiple chats at once
* **periskope\_pin\_message**: Pins or unpins a message in a chat
* **periskope\_edit\_message**: Edits a message in a chat
* **periskope\_delete\_message**: Deletes a message from a chat
* **periskope\_search\_message**: Searches for messages by content
### Contact Management
* **periskope\_create\_contact**: Creates a new WhatsApp contact
* **periskope\_list\_contacts**: Lists all WhatsApp contacts
* **periskope\_update\_contact**: Updates a WhatsApp contact
* **periskope\_update\_contact\_labels**: Updates labels for multiple contacts at once
* **periskope\_get\_contact\_by\_id**: Gets a contact by its ID
* **periskope\_search\_contact**: Searches for contacts by name
* **periskope\_check\_contacts**: Checks if given contact IDs exist on WhatsApp
### Group Management
* **periskope\_add\_participants\_to\_group**: Adds participants to a WhatsApp group
* **periskope\_remove\_participants\_from\_group**: Removes participants from a WhatsApp group
* **periskope\_promote\_participants\_to\_admins**: Promotes participants to admins in a WhatsApp group
* **periskope\_demote\_participants\_from\_admins**: Demotes participants from admins in a WhatsApp group
### Ticket Management
* **periskope\_create\_ticket**: Creates a new ticket
* **periskope\_get\_all\_tickets**: Gets all tickets
* **periskope\_get\_ticket**: Gets details about a specific ticket
* **periskope\_update\_ticket**: Updates an existing ticket
### Task Management
* **periskope\_list\_tasks**: Lists all tasks
* **periskope\_get\_task**: Gets details about a specific task
* **periskope\_create\_task**: Creates a new task
* **periskope\_update\_task**: Updates an existing task
### Knowledge Base
* **periskope\_list\_knowledge\_base**: Lists all knowledge base entries (FAQs and documents)
* **periskope\_get\_context\_by\_id**: Fetches a knowledge base FAQ entry by its context ID
* **periskope\_get\_document\_by\_id**: Gets a knowledge base document by its document ID
* **periskope\_create\_faq**: Creates a new FAQ entry in the knowledge base
* **periskope\_update\_faq**: Updates an existing FAQ entry in the knowledge base
* **periskope\_delete\_faq**: Deletes a FAQ entry from the knowledge base
* **periskope\_create\_document**: Uploads a PDF document to the knowledge base via URL or base64
* **periskope\_delete\_document**: Deletes a document from the knowledge base
### Private Notes
* **periskope\_create\_private\_note**: Creates a private internal note in a chat (not visible to customers)
* **periskope\_list\_private\_notes**: Lists all private notes
* **periskope\_get\_private\_note\_by\_id**: Gets a private note by its ID
### Reactions
* **periskope\_get\_reactions**: Gets reactions with optional filtering by chat, message, and time range
### Team Management
* **periskope\_invite\_members**: Invites new team members by email
### AI
* **periskope\_trigger\_ai\_reply**: Triggers an AI-generated reply for a specific chat message
## Use Cases
Close, reopen, reassign, and update tickets directly through natural language. Set priorities, add labels, update status, and manage ticket properties effortlessly.
*"Close all tickets assigned to John and reassign them to Sarah with high priority"*
Understand how customers feel across all your WhatsApp conversations. Fetch recent messages from any chat and ask your AI assistant to analyze tone, flag unhappy customers, and surface conversations that need urgent attention.
*"Read the last 20 messages from the latest 5 chats and tell me which customers seem frustrated"*
Send, search, forward, and delete messages on WhatsApp with simple commands. Search message history, bulk forward content, and manage message reactions all through conversation.
*"Search for messages containing 'invoice' in the last week and forward them to the accounting group"*
Create and update chats, manage group settings, and handle chat properties. Set descriptions, images, and control messaging permissions through natural language.
*"Create a new group called 'Project Alpha' with Bob, Alice, and Charlie, and set it to admin-only messages"*
Add, remove, demote, and promote group participants with ease. Manage admin privileges and participant access through simple commands.
*"Add the new interns to the 'Marketing Team' group and promote Sarah to admin"*
Search, update, and manage contact information efficiently. Add labels, update contact properties, and organize your WhatsApp contacts through conversation.
*"Find all contacts labeled as 'VIP' and update their custom properties to include their company names"*
# Respond & Escalate to Humans
Source: https://docs.periskope.app/ai/respond-and-esclate-to-humans-1
## Overview
Periskope's AI Agent can automatically respond to incoming customer messages on WhatsApp and escalate issues to the right team members when needed — without any manual intervention from your team.
If you are looking to automate customer responses and make sure the right person is always looped in at the right time, this feature is for you.
**Respond & Escalate vs AI Flagging:** Respond & Escalate enables the AI to actively reply to customers and route issues to your team, while AI Flagging categorizes messages for tracking and response time measurement. These are independent features that can be used together or separately.
***
## How does the AI decide when to respond
When an incoming message is received, Periskope AI checks if:
1. The message is a question, complaint, concern, or request for support
2. The message is from an external contact and is awaiting a response from your business
If both conditions are true, the AI activates and responds to the customer.
***
## Activation Prompt
You can customize when the AI responds by configuring the **Activation Prompt** in the Personalization section. Add your own custom rules on top of the defaults to match your business needs.
### Example
```text theme={null}
You are analyzing a customer message to determine if an AI agent should respond to it.
A message should activate the AI agent if it meets one or more of the following criteria:
- It contains a question that seeks clarification, information, or help
- It raises an issue, complaint, technical problem, or concern
- It requests an action, assistance, or support
- It appears to be waiting for a response from the business
```
***
## Escalation
Sometimes a customer message is too complex or sensitive for the AI to handle on its own. This is called an **escalation** — when the AI automatically brings your team into the conversation.
You can configure how the AI escalates using two built-in tools: **Private Notes** and **Tickets**.
***
## Private Notes
A Private Note is an internal message the AI creates directly in the chat — visible only to your team, not the customer. You can configure who gets tagged based on the type of query.
### How Private Notes work
1. The AI detects a message that requires human attention
2. It creates a private note in the chat, tagging the relevant team member
3. The tagged team member is notified and can step in immediately
4. The customer never sees the private note\\
### Configuring Private Notes
You can define tagging rules based on query type. For example:
* For message syncs, chat loads, and escalations → tag the engineering team
* For sales, pricing, demos, and discount queries → tag the sales team
***
## Tickets
For issues that need to be tracked and followed up on, the AI automatically creates a ticket and assigns it to the right person.
### How Tickets work
1. The AI detects an issue, bug, or complaint that requires follow-up
2. It automatically creates a ticket with the relevant details
3. The ticket is assigned to the appropriate team member based on the issue type
4. The AI replies to the customer informing them that a ticket has been raised and the team will get back to them soon
### Configuring Ticket Assignment
You can define assignment rules based on issue type. For example:
* For message syncs, chat loads, and escalations → assign to the relevant engineer
* For integration issues (Hubspot, Zapier, APIs) → assign to the integrations team
* For mobile app issues → assign to the mobile team\\
### Viewing Tickets
Once a ticket is created, click the **ticket symbol** in the top right corner of the chat to go directly to the ticket section. Here you can view all tickets the AI has created and track their status.
***
## How to set up Respond & Escalate
1. Go to the **AI** section in Periskope
2. Open **Personalization** and configure your **Activation Prompt**
3. Open **Built-in Tools** and enable **Private Notes** and/or **Tickets**
4. Define your tagging and assignment rules for each
5. Save your changes — the AI Agent is now live
***
## Important Notes
* The AI will never create a duplicate ticket for the same issue in the same conversation
* When a ticket is created, the AI always informs the customer in its reply
* Private notes are strictly internal and are never visible to customers
* Ticket subjects are always created in English
# AI Summaries and Responses
Source: https://docs.periskope.app/ai/summaries
Guide to generate chat summaries and craft contextual responses with Periskope AI
## Overview
Managing WhatsApp conversations can be overwhelming—long chats, missed queries, and the constant need to draft responses slow you down.
AI Summaries & Responses by Periskope AI solve this by instantly summarizing key messages and suggesting replies, helping you stay on top of conversations without the manual effort.
## How to summarize chats with Periskope AI
* Open any chat in Periskope.
* On the right-hand side, click on the **AI** tab (you'll see tabs like Overview, Properties, AI, etc.).
* In the text box, type your prompt — for example: *"Give me a summary of this chat from the last 7 days."*
* The AI will instantly generate a summary for you.
## How to craft responses with Periskope AI
Open any WhatsApp chat. On the right side panel, you'll see an AI section with a text field at the bottom. Simply type what you want the AI to do — it will understand the context of the conversation and craft a response for you.
# Translate with AI
Source: https://docs.periskope.app/ai/translate-with-ai
## Auto Translate with AI
### Overview
Auto Translate with AI helps your team communicate seamlessly with customers who speak different languages. When a customer sends a message in a foreign language, Periskope automatically translates it into your team's display language — so your team can read and respond without any confusion or delay.
If your customers speak different languages and your team often struggles to understand or respond to them efficiently, Auto Translate is for you. You can view translated messages inline, reply in your own language, and Periskope handles the translation in the background — for both incoming and outgoing messages.
***
### How does Auto Translate work
Auto Translate works in two directions —
1. **Incoming messages** — When a customer sends a message in a different language (for example, Dutch), your team will see it translated into your display language (for example, English). You don't have to do anything — it happens automatically.
2. **Outgoing messages** — When your team replies in English, the customer receives the message translated into their language. This means both sides of the conversation are always in the language each person is comfortable with.
Periskope handles all of this transparently in the background, so neither your team nor your customer needs to worry about the language barrier.
***
### How to enable Auto Translate
To turn on Auto Translate for your organization —
1. Go to **Settings** in your Periskope dashboard
2. Navigate to **Configuration**
3. Under the **Messages** section, toggle on **Enable Message Translation**
4. Select your **display language** from the dropdown — this is the language your team reads and writes in (for example, English)
5. Below that, also toggle on **Enable Auto-Translation of New Messages** — this makes sure every new incoming message is automatically translated into your display language
Once both toggles are on and your display language is selected, Auto Translate will be active across your workspace for all new incoming messages.
***
### How to translate messages manually
If you don't want to enable Auto Translate globally, you can still translate individual messages on demand. Simply click **See Translation** on any message in the chat to view it in your display language.
***
### How to enable Auto Translate for a specific chat
You can also turn Auto Translate on or off for individual chats without changing your global settings. This gives you more control over which conversations get translated —
1. Open the chat you want to enable translation for
2. In the message input area at the bottom of the chat, look for the **Auto Translate button** in the toolbar (the globe-like icon next to where you type)
3. Click it to toggle Auto Translate on for that specific chat
4. You can also select the language for that particular conversation directly from the same menu
This is helpful when you only need translation for specific customers or chats, rather than turning it on for your entire workspace.
***
# Trigger AI Reply
Source: https://docs.periskope.app/api-reference/ai/trigger-ai-reply
api-reference/openapi-generated.json POST /v1/ai/reply
Queues the org AI agent to reply to a message in a chat. Asynchronous — 200 means the run was accepted, not sent. Requires the AI agent to be available and enabled for the org and allowed in the chat.
# Authorization
Source: https://docs.periskope.app/api-reference/authorization
How to authenticate your requests to Periskope
Periskope APIs require two headers to be passed to authenticate your requests - a Bearer `Authorization` header with your apiKey and an `x-phone` header with your phone number.
## API Key 🔑
To authenticate you need to add an Authorization header with the contents of the header being `Bearer ` where `` is your API Key.
To generate an API key for your zap, you must have a periskope account. If
you don’t have one, you can sign up for a free trial
[here](https://console.periskope.app).
Navigate to the API section and click on 'Generate API Key' or click to
visit [here](https://console.periskope.app/settings/integrations/api). API key can only
be revealed once, so please keep this API key safe and at a secure place.
## x-phone header
The `x-phone` header is used to direct the request to the correct phone.
e.g. if you want to send a message to a number, the x-phone header specifies which phone must be used to send the message
The x-phone header must be a valid phone number with country code and without any special characters e.g. `919876512340`
# Accept Group Invite
Source: https://docs.periskope.app/api-reference/chat/accept-group-invite
api-reference/openapi-generated.json POST /v1/chats/accept-invite
Joins a group with the phone in the x-phone header, using the invite_code from a WhatsApp invite link.
# Add Participant to Group
Source: https://docs.periskope.app/api-reference/chat/add-participant
api-reference/openapi-generated.json POST /v1/chats/{chat_id}/add
Adds the given phone numbers to the group. Participants whose privacy settings disallow direct adds receive an invite; returns a per-participant outcome map.
# Create Group
Source: https://docs.periskope.app/api-reference/chat/create-group
api-reference/openapi-generated.json POST /v1/chats/create
Creates a WhatsApp group through the phone in the x-phone header and returns its chat object. Participants whose privacy settings disallow direct adds receive an invite instead.
# Demote Participant to Member
Source: https://docs.periskope.app/api-reference/chat/demote-participant-to-member
api-reference/openapi-generated.json POST /v1/chats/{chat_id}/demote
Demotes the given admins back to regular members. Returns a per-participant outcome map.
# Get Chat Audit Logs
Source: https://docs.periskope.app/api-reference/chat/get-chat-audit-logs
api-reference/openapi-generated.json GET /v1/chats/{chat_id}/audit-logs
Returns the audit trail of a chat — who changed what and when — newest first. Filter by performed_by and action, and restrict to a timestamp window.
# Get Chat By ID
Source: https://docs.periskope.app/api-reference/chat/get-chat-by-id
api-reference/openapi-generated.json GET /v1/chats/{chat_id}
Retrieves a chat by its chat_id, including its participants.
# Get Messages in a Chat
Source: https://docs.periskope.app/api-reference/chat/get-messages-in-chat
api-reference/openapi-generated.json GET /v1/chats/{chat_id}/messages
Returns the messages of a chat, newest first. An unknown chat_id returns an empty page.
# Get Notifications in a Chat
Source: https://docs.periskope.app/api-reference/chat/get-notifications-in-chat
api-reference/openapi-generated.json GET /v1/chats/{chat_id}/notifications
Returns the group system events of a chat (participants added or removed, admin and setting changes), newest first.
# Get Private Notes in a Chat
Source: https://docs.periskope.app/api-reference/chat/get-private-notes-in-chat
api-reference/openapi-generated.json GET /v1/chats/{chat_id}/notes
Returns the private notes of a chat, newest first. Notes are internal to the workspace and never sent to WhatsApp.
# Leave Group
Source: https://docs.periskope.app/api-reference/chat/leave-group
api-reference/openapi-generated.json POST /v1/chats/{chat_id}/leave
Makes the phone in the x-phone header leave the group. Group chats only.
# List All Chats
Source: https://docs.periskope.app/api-reference/chat/list-all-chats
api-reference/openapi-generated.json GET /v1/chats
Returns a paginated list of chats, newest first. Filter by chat_id, chat_type, label or a created_at time window.
# List All Messages
Source: https://docs.periskope.app/api-reference/chat/list-all-messages
api-reference/openapi-generated.json GET /v1/chats/messages
Returns messages across all chats, newest first. For a single chat use GET /chats/{chat_id}/messages.
# List All Notifications
Source: https://docs.periskope.app/api-reference/chat/list-all-notifications
api-reference/openapi-generated.json GET /v1/chats/notifications
Returns group system events (participants added or removed, admin and setting changes) across all chats, newest first.
# Mark chat as read
Source: https://docs.periskope.app/api-reference/chat/mark-read
api-reference/openapi-generated.json POST /v1/chats/{chat_id}/read
Marks all messages in the chat as read, clearing its unread count.
# Update Chat Access
Source: https://docs.periskope.app/api-reference/chat/override-chat-access
api-reference/openapi-generated.json PATCH /v1/chats/access
Overrides member access on one or more chats via a map of member email to access flag. Merges into existing overrides unless replace is true. Pass null or an empty object as access with replace true to remove every override.
# Promote Participant to Admin
Source: https://docs.periskope.app/api-reference/chat/promote-participant-to-admin
api-reference/openapi-generated.json POST /v1/chats/{chat_id}/promote
Promotes the given participants to group admin. Returns a per-participant outcome map.
# Generate a new invite link for a chat
Source: https://docs.periskope.app/api-reference/chat/refresh-invite
api-reference/openapi-generated.json POST /v1/chats/{chat_id}/invite
Revokes the invite link of the group and returns a new one — the old link stops working.
# Remove Participant from Group
Source: https://docs.periskope.app/api-reference/chat/remove-participant
api-reference/openapi-generated.json POST /v1/chats/{chat_id}/remove
Removes the given participants from the group. Returns a per-participant outcome map.
# Update Chat
Source: https://docs.periskope.app/api-reference/chat/update-chat
api-reference/openapi-generated.json PATCH /v1/chats/{chat_id}
Updates the Periskope attributes of a chat — labels, custom_properties, assigned_to and/or status. At least one is required. Pass null (or an empty value) to clear labels or assigned_to; custom_properties is merged per key.
# Update Chat AI Settings
Source: https://docs.periskope.app/api-reference/chat/update-chat-ai-settings
api-reference/openapi-generated.json PATCH /v1/chats/{chat_id}/ai
Toggles the AI permissions of this chat: whether the AI agent may reply to messages and whether AI flagging may flag them. At least one flag is required; omitted flags are unchanged.
# Update Chat Labels
Source: https://docs.periskope.app/api-reference/chat/update-chat-labels
api-reference/openapi-generated.json PATCH /v1/chats/labels
Applies labels to one or more chats; unknown label names are created automatically. Replaces the current labels unless replace is false. Pass null or an empty string as labels to remove every label.
# Update Group Settings
Source: https://docs.periskope.app/api-reference/chat/update-group-settings
api-reference/openapi-generated.json POST /v1/chats/{chat_id}/settings
Updates the WhatsApp settings of a group — name, description, icon, admin-only restrictions and disappearing messages. At least one is required; group chats only.
# Check Contact Exists
Source: https://docs.periskope.app/api-reference/contacts/check-contact
api-reference/openapi-generated.json POST /v1/contacts/check
Checks whether each given number is registered on WhatsApp, live through the phone in the x-phone header (must be connected).
# Create Contact
Source: https://docs.periskope.app/api-reference/contacts/create-contact
api-reference/openapi-generated.json POST /v1/contacts/create
Creates a contact, or updates the existing one with the same contact_id (upsert). contact_id must be a possible phone number.
# Get Contact By ID
Source: https://docs.periskope.app/api-reference/contacts/get-contact-by-id
api-reference/openapi-generated.json GET /v1/contacts/{contact_id}
Looks up a contact by phone number, including the chat_ids of every chat it participates in.
# Get Contacts
Source: https://docs.periskope.app/api-reference/contacts/get-contacts
api-reference/openapi-generated.json GET /v1/contacts
Returns a paginated list of contacts, ordered by name. Contacts are org-level — no x-phone header needed.
# Update Contact
Source: https://docs.periskope.app/api-reference/contacts/update-contact
api-reference/openapi-generated.json PATCH /v1/contacts/{contact_id}
Updates the name, internal flag and/or labels of a contact — at least one is required. Name changes apply on Periskope only.
# Update Contact Labels
Source: https://docs.periskope.app/api-reference/contacts/update-contact-labels
api-reference/openapi-generated.json PATCH /v1/contacts/labels
Sets the labels of one or more contacts; label names that do not exist yet are created automatically. Pass null or an empty string as labels to remove every label.
# WhatsApp Message Ack Status
Source: https://docs.periskope.app/api-reference/delivery-status
Understanding WhatsApp acknowledgment statuses and what they mean for your messages
## Overview
WhatsApp uses acknowledgment (ACK) statuses to indicate the delivery and read status of messages. Periskope displays these statuses using visual indicators to help you understand the current state of your messages.
**Important Notes:**
* ACK values are **monotonic** - they only increase (never decrease) once a message is sent
* For group chats, check the `delivery_info` object in the message payload for detailed participant-level delivery (`delivered_count`) and read (`read_count`) statistics
* The ACK status reflects the highest acknowledgment level achieved so far
## Message Status Types
### Message Failed
The message has failed to be sent. This indicates a delivery failure.
**What to do:** Please retry sending the message or restart the phone connection.
***
### Pending Send
The message is not sent yet. It's queued and waiting to be sent to the WhatsApp server.
**What this means:** The message is in your outbox and will be sent when the connection is available.
***
### Sent to WhatsApp
Message has been sent to the WhatsApp servers, BUT is awaiting confirmation from WhatsApp
**What this means:**
* Messages typically should not be in the 1 state for more than a couple of seconds. If it is, please reset the connection and scan the QR again
***
### Delivered to WhatsApp
Message was delivered to the WhatsApp servers, but is awaiting delivery confirmation from all recipients
**What this means:**
* For individual chats: Awaiting delivery confirmation from the recipient
* For group chats: The message has been delivered to at least one participant (but not necessarily all), but awaiting delivery confirmation from the rest. Check `delivery_info.delivered_count` for the exact number of participants who received it
***
### Delivered to all recipients
Message was delivered to all recipients
**What this means:** For private chats, it was delivered to the recipient. For group chats, all group participants have received the message on their devices
***
### Read by all
Message was read (or played in case of audio/video messages) by all the recipients (blue double tick).
**What this means:**
* For individual chats: The message has been read by the recipient. This status will typically appear only if the recipient has read receipts enabled in their WhatsApp privacy settings.
## Understanding Group Chat Delivery
For group chats, the `ack` value provides a summary status, but the `delivery_info` object in the message payload contains detailed statistics:
* `delivered_count`: Number of participants who have received the message
* `read_count`: Number of participants who have read the message
**Example:**
* A group with 10 participants might have `ack: 2` (delivered to at least one) but `delivery_info.delivered_count: 7` (delivered to 7 participants)
* The `ack` value will increase to `3` only when all participants have received it
## Troubleshooting
### Message Stuck at Status 0 or 1
* Check your phone connection status
* Try restarting your phone on Periskope
* Ensure that WhatsApp on your phone is updated to the latest version
* Verify your internet connection is stable
### Message Failed (Status -1)
* Ensure that WhatsApp on your phone is updated to the latest version
* Verify the recipient's phone number is correct and not formatted incorrectly
* Check if the recipient has blocked your number
* Try restarting your phone on Periskope
* For group chats, verify the group still exists and your number hasn't been removed
### ACK Status Not Advancing
* ACK values are monotonic (they never decrease)
* If a message shows `ack: 2` for a long time, it may mean:
* The recipient hasn't read it yet (for individual chats)
* Not all group participants have read it (for group chats)
* Read receipts are disabled
* Network issues or WhatsApp server delays can also cause status updates to be delayed
## API Integration
When integrating with Periskope's API, these status codes are returned as integers in the message object's `ack` field.
**For group chats**, also check the `delivery_info` object:
```json theme={null}
{
"ack": 2,
"delivery_info": {
"read": {
"919537851844@c.us": 1737976090690
},
"pending": [],
"delivered": {
"919537851844@c.us": 1737976082277
},
"read_count": 1,
"delivered_count": 1
}
}
```
You can use these values to build custom notification systems or delivery tracking in your applications.
## Webhook Integration
You can track acknowledgment status changes in real-time using the [`message.ack.updated`](/api-reference/webhooks/message.ack.updated) webhook event, which fires whenever a message's acknowledgment status changes.
The webhook payload will include both the `ack` value and, for group chats, the updated `delivery_info` with current counts.
# Introduction
Source: https://docs.periskope.app/api-reference/introduction
Automate your WhatsApp with Periskope APIs
Welcome to the Periskope API documentation. Periskope APIs lets you extend the capabilities of WhatsApp and automate actions on your WhatsApp account and the Periskope platform.
The Periskope API is designed based on REST principles has predictable, responsibly named URLs and returns simple JSON objects. Our APIs ensure straightforward and effective communication with your Periskope account, offering capabilities such as sending messages, raising tickets, creating groups etc.
We encourage responsible usage of the APIs. Follow these best practices and recommendations for safe actions on WhatsApp - [https://docs.periskope.app/get-started/best-practices](https://docs.periskope.app/get-started/best-practices)
## Prerequisites
1. **Sign up for a free account on Periskope**: To use the Periskope API, you need to have an active Periskope account. If you don’t have one, you can sign up for a 7-day free trial here.
2. **Scan the QR code from WhatsApp to connect your phone**: A connected phone is required to use the APIs
3. **Generate an API Key**: An API key is required for authentication and can be generated from your Periskope settings [here](https://console.periskope.app/settings/integrations/api).
## Setting up APIs on Postman [🔗](https://www.postman.com/periskope/workspace/periskope-platform-api)
To begin, search for the `Periskope Platform API` collection on Postman or
click here to
[open](https://www.postman.com/periskope/workspace/periskope-platform-api).
This collection contains all the requests you need to work with our API.
* To fork the collection, right click on the collection.
* Click on the `Create a Fork` button in the menu.
* Now you can choose `name` of the collection and the `workspace` you want to add it to.
* This will fork the collection into `your workspace`
For `Postman` users, we've made setting up testing for Periskope APIs on `Postman` easy for you.
You don't need to pass `x-phone` or `authorization` header with each request.
Just need to update `orgPhone` and `apiKey` in the collection variables in order to automatically pass the headers into each request.
In case, you're using any other tools for testing APIs, you'll need to pass the headers manually for each request.
#### If you're using Postman, follow the steps given below -
* You need to add `apiKey` and `orgPhone` variables in the collection. You can do this by clicking on the collection and then clicking on the `Variables` tab.
* In the `Variables` tab, update the value of the `apiKey` you generated in the previous step.
* You also need to update the value of `orgPhone` with your phone number (with country code and without any special characters) to validate an API request. For e.g. `919876512340`.
That's it! Now you can start testing the Periskope APIs from your Postman collection.
# Create Document
Source: https://docs.periskope.app/api-reference/knowledge-base/create-document
api-reference/openapi-generated.json POST /v1/knowledge-base/document/create
Ingests a PDF into the AI knowledge base. Provide the document as exactly one of document.url, document.base64 or document.file.
# Create FAQ
Source: https://docs.periskope.app/api-reference/knowledge-base/create-faq
api-reference/openapi-generated.json POST /v1/knowledge-base/faq/create
Creates an FAQ — a question/answer pair the AI agent learns to answer from. Its embedding is generated automatically. The entry starts inactive unless is_active is sent as true.
# Delete Document
Source: https://docs.periskope.app/api-reference/knowledge-base/delete-document
api-reference/openapi-generated.json DELETE /v1/knowledge-base/document/{document_id}
Permanently deletes an uploaded document by document_id — every chunk extracted from it plus the stored PDF.
# Delete FAQ
Source: https://docs.periskope.app/api-reference/knowledge-base/delete-faq
api-reference/openapi-generated.json DELETE /v1/knowledge-base/faq/{context_id}
Permanently deletes an FAQ by its context_id. Only entries of type faq are deleted.
# Get All Knowledge Base Items
Source: https://docs.periskope.app/api-reference/knowledge-base/get-all-knowledge-base
api-reference/openapi-generated.json GET /v1/knowledge-base
Returns every entry in the AI knowledge base — FAQs, document chunks and self-learned entries — newest first.
# Get Document by ID
Source: https://docs.periskope.app/api-reference/knowledge-base/get-document-by-id
api-reference/openapi-generated.json GET /v1/knowledge-base/document/{document_id}
Returns every chunk extracted from an uploaded document, by its document_id.
# Get FAQ by ID
Source: https://docs.periskope.app/api-reference/knowledge-base/get-faq-by-id
api-reference/openapi-generated.json GET /v1/knowledge-base/faq/{context_id}
Fetches a knowledge-base entry by its context_id.
# Update FAQ
Source: https://docs.periskope.app/api-reference/knowledge-base/update-faq
api-reference/openapi-generated.json PATCH /v1/knowledge-base/faq/{context_id}
Updates the FAQ addressed by the path context_id. Send question and answer together to replace the text and regenerate its embedding (attachments are then cleared unless resent); attachments and is_active can also be updated alone — omitted fields stay unchanged.
# Migrate Media URL
Source: https://docs.periskope.app/api-reference/media/migrate-url
POST https://api.periskope.app/v1/media/migrate-url
Convert a legacy Google Cloud Storage media URL to the new Periskope media URL format
This endpoint converts a legacy `storage.googleapis.com` attachment URL to the new Periskope media URL format (`https://api.periskope.app/app/media/...`).
You can also pass an existing Periskope media URL to refresh its access token — useful when a private link has expired and you need a fresh one.
The media file must belong to the organization of the API key used. URLs from other organizations or non-Periskope buckets will return an error.
### Headers
Bearer token with your API key e.g. `Bearer `
### Body
The media URL to migrate. Either a legacy `storage.googleapis.com` attachment URL or an existing Periskope media URL.
Access mode for the returned URL. One of `private` or `public`.
* `private` — returns a tokenized link that expires
* `public` — returns a bare link without a token
If omitted, follows your organization's [Media Privacy](/features/media-privacy) setting.
Validity of the returned link in seconds. Only valid for private links — returns an error if passed for a public link. Clamped between `60` (1 minute) and `604800` (7 days). Defaults to your organization's configured link expiry (24 hours unless changed).
### Response
The migrated Periskope media URL. Includes an access token (`?jwt=...`) when access is private.
The access mode applied to the returned URL — `private` or `public`.
Validity of the returned link in seconds. Only present for private links.
```bash cURL theme={null}
curl --request POST \
--url https://api.periskope.app/v1/media/migrate-url \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"url": "https://storage.googleapis.com/periskope-attachments/2997dd64-89bf-48d3-9a22-b314fca017e5/919876543210/msg_ABCDEF123/file.jpg",
"access": "private",
"expires_in_seconds": 86400
}'
```
```json 200 OK theme={null}
{
"url": "https://api.periskope.app/app/media/periskope-attachments/2997dd64-89bf-48d3-9a22-b314fca017e5%2F919876543210%2Fmsg_ABCDEF123%2Ffile.jpg?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"access": "private",
"expires_in_seconds": 86400
}
```
```json 400 Error theme={null}
{
"error": "URL belongs to a different organization"
}
```
# Migrate Media URLs (Batch)
Source: https://docs.periskope.app/api-reference/media/migrate-url-batch
POST https://api.periskope.app/v1/media/migrate-url/batch
Convert up to 1000 legacy Google Cloud Storage media URLs to the new Periskope media URL format in a single request
This endpoint converts up to **1000** legacy `storage.googleapis.com` attachment URLs (or existing Periskope media URLs) to the new Periskope media URL format in a single request.
Each URL succeeds or fails independently — `results[i]` in the response corresponds to `urls[i]` in the request, so one invalid URL does not fail the whole batch.
All media files must belong to the organization of the API key used. URLs from other organizations or non-Periskope buckets fail individually with an `error` in their result entry.
### Headers
Bearer token with your API key e.g. `Bearer `
### Body
The media URLs to migrate. Maximum `1000` URLs per request.
Access mode for the returned URLs. One of `private` or `public`.
* `private` — returns tokenized links that expire
* `public` — returns bare links without a token
If omitted, follows your organization's [Media Privacy](/features/media-privacy) setting.
Validity of the returned links in seconds. Only valid for private links — returns an error if passed for public links. Clamped between `60` (1 minute) and `604800` (7 days). Defaults to your organization's configured link expiry (24 hours unless changed). A single token is minted and shared across all URLs in the batch.
### Response
One result per input URL, in the same order as the request.
Index of the URL in the request `urls` array.
Whether this URL was migrated successfully.
The migrated Periskope media URL. Only present when `success` is `true`.
Reason the URL could not be migrated. Only present when `success` is `false`.
Number of URLs migrated successfully.
Number of URLs that failed to migrate.
The access mode applied to the returned URLs — `private` or `public`.
Validity of the returned links in seconds. Only present for private links.
```bash cURL theme={null}
curl --request POST \
--url https://api.periskope.app/v1/media/migrate-url/batch \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"urls": [
"https://storage.googleapis.com/periskope-attachments/2997dd64-89bf-48d3-9a22-b314fca017e5/919876543210/msg_ABCDEF123/file.jpg",
"https://storage.googleapis.com/periskope-attachments/other-org-id/919876543210/msg_XYZ789/file-2.pdf"
],
"access": "private",
"expires_in_seconds": 86400
}'
```
```json 200 OK theme={null}
{
"results": [
{
"index": 0,
"success": true,
"url": "https://api.periskope.app/app/media/periskope-attachments/2997dd64-89bf-48d3-9a22-b314fca017e5%2F919876543210%2Fmsg_ABCDEF123%2Ffile.jpg?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
{
"index": 1,
"success": false,
"error": "URL belongs to a different organization"
}
],
"migrated_count": 1,
"failed_count": 1,
"access": "private",
"expires_in_seconds": 86400
}
```
# Delete Member
Source: https://docs.periskope.app/api-reference/members/delete-member
api-reference/openapi-generated.json DELETE /v1/members/{email_id}
Removes a member from the org by email. Permanent — access is lost immediately.
# Invite Members
Source: https://docs.periskope.app/api-reference/members/invite-members
api-reference/openapi-generated.json POST /v1/members/invite
Invites people to the org by email. New emails become pending members and receive an invite email; existing members are unchanged.
# Update Member Access
Source: https://docs.periskope.app/api-reference/members/update-member-access
api-reference/openapi-generated.json PATCH /v1/members/access
Replaces the chat access scope (labels and orgPhones) of members with role member. Both dimensions are written on every call — an omitted or null dimension is cleared, not left unchanged.
# Broadcast Message
Source: https://docs.periskope.app/api-reference/message/broadcast-message
api-reference/openapi-generated.json POST /v1/message/broadcast
Sends the same message (text, media or poll) to many chats — from chat_ids, or every chat carrying the given label. One credit per recipient; rejected up front when credits are insufficient.
# Delete a Broadcast
Source: https://docs.periskope.app/api-reference/message/delete-broadcast
api-reference/openapi-generated.json DELETE /v1/message/broadcast/{broadcast_id}
Cancels a scheduled broadcast or stops one in progress. Unsent messages are cancelled and their credits refunded.
# Delete Message
Source: https://docs.periskope.app/api-reference/message/delete-message
api-reference/openapi-generated.json POST /v1/message/{message_id}/delete
Deletes a message for everyone in the chat. Permanent, and subject to the WhatsApp delete-for-everyone time window.
# Edit Message
Source: https://docs.periskope.app/api-reference/message/edit-message
api-reference/openapi-generated.json POST /v1/message/{message_id}/edit
Edits the text (or media caption) of a message sent by the phone. Media content and polls cannot be edited.
# Forward Message
Source: https://docs.periskope.app/api-reference/message/forward-message
api-reference/openapi-generated.json POST /v1/message/{message_id}/forward
Forwards a message to one or more chats. Returns a map of forward_chat_id to success.
# Get Message
Source: https://docs.periskope.app/api-reference/message/get-message
api-reference/openapi-generated.json GET /v1/message/{message_id}
Retrieves a message record with its reactions. Accepts a message_id or the unique_id from the send response.
# List All Message Queues
Source: https://docs.periskope.app/api-reference/message/list-queue-jobs
api-reference/openapi-generated.json POST /v1/message/queues
Lists the jobs retained in the send queue of the phone. Pass broadcast_id to track a broadcast, or queue_id for a single job.
# Get Message Status
Source: https://docs.periskope.app/api-reference/message/message-status
api-reference/openapi-generated.json GET /v1/message/{unique_id}/status
Tracks a message sent via POST /message/send by its unique_id: queued, scheduled, sending or failed while queued, then sent, delivered, read or played.
# Pin Message
Source: https://docs.periskope.app/api-reference/message/pin-message
api-reference/openapi-generated.json POST /v1/message/{message_id}/pin
Pins a message in its chat (pin: true) or unpins it. time sets the pin duration in days: 1, 7 or 30 (default 30).
# Purge Message Queues
Source: https://docs.periskope.app/api-reference/message/purge-queue-jobs
api-reference/openapi-generated.json POST /v1/message/queues/purge
Removes unsubmitted jobs from the send queue of the phone, by queue_ids or broadcast_id. Warning: an empty body purges the entire queue.
# Get Status of Message Queues
Source: https://docs.periskope.app/api-reference/message/queue-health
api-reference/openapi-generated.json GET /v1/message/queues/health
Returns live counters of the send queue of the phone: running state plus active, pending, completed and failed job counts.
# React to Message
Source: https://docs.periskope.app/api-reference/message/react-to-message
api-reference/openapi-generated.json POST /v1/message/{message_id}/react
Adds an emoji reaction to a message; reacting again replaces the previous reaction. Pass an empty string or null as reaction to remove it.
# Send Message
Source: https://docs.periskope.app/api-reference/message/send-message
api-reference/openapi-generated.json POST /v1/message/send
Sends a message (text, media and/or poll) to a chat from the phone in the x-phone header. For group chats the header can be omitted — a connected phone that is in the group is selected automatically, within the token's phone scopes. Sending is asynchronous — track the returned unique_id via GET /message/{unique_id}/status.
# Send Sync Message
Source: https://docs.periskope.app/api-reference/message/send-message-sync
api-reference/openapi-generated.json POST /v1/message/send-sync
Sends a message like POST /message/send (including automatic phone selection for group chats when x-phone is omitted), then waits up to sync_timeout seconds (default 20) for WhatsApp to accept or reject the message. When accepted in time the response carries the sent message record (status sent). When the send fails in time — WhatsApp rejected it (ack -1), or the phone gave up before it reached WhatsApp, for example because the number is not on WhatsApp — the request fails with a 400 MESSAGE_SEND_FAILED error carrying the reason, so the caller can retry — typically from another phone via the x-phone header. Otherwise it falls back to the asynchronous queued response.
# Send Private Notes
Source: https://docs.periskope.app/api-reference/notes/create-private-notes
api-reference/openapi-generated.json POST /v1/notes/create
Adds a private note (message, media, or both) to a chat. Notes are internal — never sent to WhatsApp. @-mentioning a member email creates a task for them.
# Get Private Note
Source: https://docs.periskope.app/api-reference/notes/get-private-note
api-reference/openapi-generated.json GET /v1/notes/{note_id}
Looks up a private note by its note_id. Responds 200 with null (not 404) when no note matches.
# List All Private Notes
Source: https://docs.periskope.app/api-reference/notes/list-all-private-notes
api-reference/openapi-generated.json GET /v1/notes
Returns private notes across all chats, newest first.
# The Chat Notification Object
Source: https://docs.periskope.app/api-reference/objects/the-chat-notification-object
A chat notification — a group system event such as participants being added or removed, admin changes or setting changes. Stored in tbl_chat_notifications.
```json The Chat Notification Object theme={null}
{
"notification_id": "true_120363000000000000@g.us_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_911111111111@c.us_add",
"org_id": "00000000-0000-0000-0000-000000000000",
"org_phone": "911111111111@c.us",
"chat_id": "120363000000000000@g.us",
"author": "911111111111@c.us",
"body": null,
"type": "add",
"recipientids": [
"922222222222@c.us"
],
"id": {
"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"fromMe": true,
"remote": "120363000000000000@g.us",
"serialized": "true_120363000000000000@g.us_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_911111111111@c.us_add"
},
"timestamp": "2026-01-15T09:30:00+00:00",
"unique_id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"metadata": null,
"call_metadata": null
}
```
**Attributes**
Unique id of the notification, in the form \*\*\*\*\
Id of the organization the notification belongs to
Org phone (WhatsApp account) the notification was observed on, as country code + number suffixed with @c.us
Chat the notification belongs to
Participant who performed the action (\\@c.us)
Text of the notification, when WhatsApp provides one
Kind of group event, e.g. 'add', 'remove', 'promote', 'demote', 'leave', 'invite', 'create', 'subject', 'picture', 'memberaddmode\_true', 'memberaddmode\_false'
Participants affected by the event (e.g. the contacts that were added or removed).
Raw WhatsApp id object of the notification (id, remote, fromMe, serialized)
When the event happened, as an ISO 8601 UTC timestamp
WhatsApp id of the notification without the id prefix
Extra event metadata, when present
Call details for call notifications, when present
# The Chat Object
Source: https://docs.periskope.app/api-reference/objects/the-chat-object
A WhatsApp chat (1-1 conversation or group) synced into the workspace, together with its Periskope attributes (labels, assignee, custom properties, status).
```json The Chat Object theme={null}
{
"org_id": "00000000-0000-0000-0000-000000000000",
"chat_id": "120363000000000000@g.us",
"org_phone": "911111111111@c.us",
"chat_name": "Example Group",
"chat_type": "group",
"chat_image": "https://example.com/images/example.jpg",
"invite_link": "https://chat.whatsapp.com/invite/AAAAAAAAAAAAAAAAAAAAAA",
"label_ids": {
"label-aaaaaaaaaaaaaaaa": true
},
"labels": [
"priority"
],
"custom_properties": {
"Custom Property": "Value"
},
"assigned_to": "user@example.com",
"chat_access": {
"user@example.com": true
},
"group_description": "A sample group description",
"info_admins_only": false,
"messages_admins_only": false,
"add_members_admins_only": false,
"member_count": 12,
"members": {
"key": {
"org_id": "00000000-0000-0000-0000-000000000000",
"chat_id": "120363000000000000@g.us",
"org_phone": "911111111111@c.us",
"contact_id": "922222222222@c.us",
"contact_name": "John Doe",
"contact_image": "https://example.com/images/example.jpg",
"contact_color": "#000000",
"is_admin": false,
"is_super_admin": false,
"is_internal": false
}
},
"latest_message": {
"message_id": "true_120363000000000000@g.us_AAAAAAAAAAAAAAAAAAAAAA",
"org_id": "00000000-0000-0000-0000-000000000000",
"org_phone": "911111111111@c.us",
"chat_id": "120363000000000000@g.us",
"body": "Hello! This is a sample message.",
"message_type": "chat",
"from_me": true,
"author": "922222222222@c.us",
"ack": "4",
"timestamp": "2026-01-15T09:30:00+00:00",
"media": {
"path": "https://example.com/images/example.jpg",
"mimetype": "image/png",
"filename": "image.png"
},
"mentioned_ids": [
"922222222222@c.us"
],
"performed_by": "api",
"quoted_message_id": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"sender_phone": "911111111111@c.us",
"sent_message_id": "00000000-0000-0000-0000-000000000000",
"delivery_info": {
"delivered": {
"key": null
},
"read": {
"key": null
},
"pending": [
null
],
"read_count": null,
"delivered_count": null
},
"is_deleted": null,
"is_forwarded": null,
"is_starred": null,
"has_media": null,
"unique_id": "AAAAAAAAAAAAAAAAAAAAAA",
"updated_at": "2026-01-15T09:31:12.884+00:00"
},
"latest_message_timestamp": "2026-01-15T09:30:00+00:00",
"message_unread_count": 0,
"flag_count_map": {
"key": null
},
"parent_community_id": null,
"is_archived": false,
"group_metadata": {},
"is_muted": false,
"is_exited": false,
"closed_at": null,
"created_at": "2026-01-10T08:00:00+00:00",
"updated_at": "2026-01-15T09:30:00.025233+00:00"
}
```
**Attributes**
The unique identifier of the organization that owns the WhatsApp account.
The unique identifier of the WhatsApp chat (format: \{phone\_number}@c.us for individual chats or \{group\_id}@g.us for groups).
The organization phone that the chat belongs to (in the format \{phone\_number}@c.us).
The display name of the chat. For groups, this is the group name. For individual chats, this is the contact's name.
The type of chat. Can be `group`, `user`, or `business`.
The URL of the chat's profile image.
The invite link of the chat. Group chats only, and only when the phone is an admin.
A map of label identifiers associated with the chat, where keys are label IDs and values are booleans.
An array of labels associated with the chat.
A map of custom properties associated with the chat. Values depend on the property type: dropdown, text, date.
The email address of the user assigned to this chat. Absent when unassigned.
A map of user access permissions, where keys are email addresses and values are booleans. Absent when no per-chat overrides exist.
The description text for group chats. Group chats only.
Indicates if only admins can modify group info.
Indicates if only admins can send messages in the group.
Indicates if only admins can add new members to the group.
The total number of participants in the chat.
A map of members in the chat, keyed by WhatsApp ID (format: \{phone\_number}@c.us). Only returned when fetching a single chat by id — list results omit it.
The unique identifier of the organization that owns the WhatsApp account.
The unique identifier of the WhatsApp chat.
The WhatsApp ID of the organization's account (format: \{phone\_number}@c.us).
The WhatsApp ID of the member (format: \{phone\_number}@c.us).
The display name of the member.
The URL of the member's profile image.
The hex color code assigned to the member in Periskope's UI.
Indicates if the member has admin privileges in the chat.
Indicates if the member has super admin privileges in the chat.
Indicates if the member is an internal user of the organization.
An object containing details about the latest message sent in the chat.
Unique id of the message, in the form \*\*\
Id of the organization the message belongs to
Org phone (WhatsApp account) the message was sent or received on, as country code + number suffixed with @c.us
Chat the message belongs to — \\@c.us for 1-1 chats, \@g.us for group chats
Text content of the message, or the caption of a media message.
Content type of the message: 'chat' for text, otherwise the media/attachment type (e.g. 'image', 'video', 'document', 'audio', 'ptt', 'sticker', 'location', 'poll\_creation')
true when the message was sent by the org phone, false when it was received from the contact
In group chats, the participant who sent the message (\\@c.us).
WhatsApp acknowledgement level of an outgoing message as a string: '1' sent, '2' delivered, '3' read, '4' played/read.
When the message was sent, as an ISO 8601 UTC timestamp
Media attached to the message (may also carry dimensions, size, thumbnail).
URL of the media file
MIME type of the media file
Filename of the media file, when applicable
Contact ids @-mentioned in the message body.
Member email or "api" when the message was sent through Periskope.
message\_id of the message this message replies to. Absent when the message is not a reply.
Phone that sent the message, as country code + number suffixed with @c.us
Internal id assigned when the message was sent via the Periskope queue. Absent for received messages.
Per-recipient delivery and read receipts of an outgoing message.
Map of recipient contact\_id to delivery epoch-ms timestamp
Map of recipient contact\_id to read epoch-ms timestamp
Recipients the message has not been delivered to yet
Number of recipients who have read the message
Number of recipients the message was delivered to
true when the message was deleted for everyone.
true when the message was forwarded.
true when the message is starred.
true when the message carries media.
WhatsApp message id without the from\_me/chat\_id prefix — accepted by message endpoints in place of the full message\_id
When the message record was last updated (e.g. by a delivery receipt), as an ISO 8601 UTC timestamp
Timestamp of the most recent message in the chat, as an ISO 8601 UTC timestamp.
The number of unread messages in the chat.
A map of flagged messages, where keys are phone numbers and values are flagged messages count.
Indicates the id of the parent community for the group.
Indicates if the chat has been archived.
Additional raw group metadata synced from WhatsApp, when present
Indicates if notifications for this chat are muted.
Indicates if the organization has left this chat.
The timestamp when the chat was closed, if applicable, as an epoch timestamp in milliseconds. Absent while the chat is open.
The ISO 8601 formatted timestamp when the chat was created.
The ISO 8601 formatted timestamp when the chat was last updated.
# The Contact Object
Source: https://docs.periskope.app/api-reference/objects/the-contact-object
A WhatsApp contact known to the workspace — synced from a connected phone's address book and chats, or created via the API. Contacts belong to the org as a whole, not to a single phone. Labels on a contact are shared with the contact's 1-1 chat.
```json The Contact Object theme={null}
{
"org_id": "00000000-0000-0000-0000-000000000000",
"contact_id": "911111111111@c.us",
"contact_name": "John Doe",
"username": "jane.doe",
"contact_type": "user",
"is_wa_contact": true,
"is_my_contact": true,
"is_internal": false,
"is_imported": true,
"contact_image": "https://example.com/files/image.png",
"contact_color": "#DC2626",
"label_ids": {
"label-aaaaaaaaaaaa": true
},
"labels": [
"lead"
],
"chat_ids": [
"911111111111@c.us",
"120363000000000000@g.us"
],
"updated_at": "2026-01-15T09:30:00.000Z"
}
```
**Attributes**
Id of the organization the contact belongs to
Unique id of the contact within the org: country code + number suffixed with @c.us. Use the number part (with or without the suffix) wherever a contact\_id parameter is expected.
Display name of the contact — the Periskope-set name when one was saved via the API or dashboard, otherwise the WhatsApp verified name, address-book name or push name. null when no name is known from any source.
WhatsApp username of the contact. null when the contact has not set one or it has not been synced yet.
Type of the WhatsApp account: 'user' for a personal account, 'business' for a business account. null when not yet synced.
Whether the number is registered on WhatsApp, as reported by the connected phone. null when not yet synced.
Whether the contact is saved in the connected phone's address book. null when not yet synced.
Whether the contact is marked as internal (e.g. a teammate). Messages from internal contacts are not flagged for response. null when the flag was never set.
true when the contact was created via the API or an import rather than synced from a phone. null for synced contacts.
URL of the contact's WhatsApp profile picture. null when the contact has no picture or it is not accessible.
Hex color assigned to the contact, used to render it in the dashboard. null when no color is assigned.
Map of label\_id to boolean for the labels on the contact. Labels on a contact are shared with its 1-1 chat. An empty object when the contact has no labels.
Names of the labels currently on the contact, resolved from label\_ids
Ids of the chats the contact participates in — the 1-1 chat (\\@c.us) and any group chats (\@g.us) shared with the workspace. Contains a single null entry when the contact is not a participant of any chat.
When the contact record was last updated, as an ISO 8601 timestamp
# The Message Object
Source: https://docs.periskope.app/api-reference/objects/the-message-object
A WhatsApp message record. Responses may include additional raw fields of the underlying record (id, author, links, location, vcards, is_forwarded, has_media, message_ticket_id, ...).
```json The Message Object theme={null}
{
"message_id": "true_911111111111@c.us_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"unique_id": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"org_id": "00000000-0000-0000-0000-000000000000",
"org_phone": "911111111111@c.us",
"chat_id": "120363000000000000@g.us",
"body": "Hello World",
"message_type": "chat",
"timestamp": "2026-01-15T09:30:00+00:00",
"from_me": true,
"ack": "3",
"performed_by": "api",
"sender_phone": "911111111111@c.us",
"quoted_message_id": null,
"broadcast_id": null,
"is_deleted": null,
"media": {
"path": "https://example.com/files/image.png",
"mimetype": "image/png",
"filename": "image.png",
"size": 24576,
"dimensions": {
"width": null,
"height": null,
"ar": null
},
"thumbnail": null
},
"mentioned_ids": [],
"prev_body": null,
"sent_message_id": "00000000-0000-0000-0000-000000000000",
"delivery_info": {
"delivered": {
"911111111111@c.us": 1737967705196
},
"read": {
"911111111111@c.us": 1737967704763
},
"pending": [],
"delivered_count": 1,
"read_count": 1
},
"poll_info": {},
"poll_results": {},
"flag_status": null,
"updated_at": "2026-01-15T09:35:38.221+00:00",
"reactions": [
{
"reaction_id": "true_911111111111@c.us_AAAAAAAAAAAAAAAAAAAAAA",
"message_id": "true_911111111111@c.us_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"unique_id": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"chat_id": "911111111111@c.us",
"org_id": "00000000-0000-0000-0000-000000000000",
"org_phone": "911111111111@c.us",
"sender_id": "911111111111@c.us",
"reaction": "😄",
"read": true,
"timestamp": "2026-01-15T09:31:57.008+00:00"
}
]
}
```
**Attributes**
WhatsApp message id, in the form \*\*\. Accepted wherever a message\_id path parameter is expected.
Provisional id assigned when the message was queued via the API — the same value returned by POST /message/send. Also accepted wherever a message\_id path parameter is expected. null for messages that did not originate from the API.
Id of the organization the message belongs to
Org phone (WhatsApp account) the message was sent or received on, suffixed with @c.us
Chat the message belongs to — \\@c.us for 1-1 chats, \@g.us for group chats
Text content of the message, or the caption for media messages. null when the message has no text.
Content type of the message: 'chat' for text, or e.g. 'image', 'video', 'document', 'audio', 'ptt', 'poll\_creation', 'location', 'vcard'
When the message was sent, as an ISO 8601 timestamp
Whether the message was sent by the org phone (true) or received from the contact (false)
Delivery acknowledgement level as a string: '-1' failed, '0' pending, '1' sent, '2'/'3' delivered, '4' read, '5' played. null when unknown.
Who triggered the message from Periskope: a member's email, or 'api' when sent via the API. null for messages sent from the phone itself.
chat\_id of the actual sender — in group chats this is the participant who sent the message
message\_id of the message this one replies to (set via reply\_to when sending). null when not a reply.
Id of the broadcast that produced this message, when it was sent via POST /message/broadcast. null otherwise.
Whether the message has been deleted for everyone. null when never deleted.
Media attached to the message. null for text-only messages.
URL of the media content
MIME type of the media file
Filename of the media — the filename provided when sending, or one derived from the url
Size of the media file in bytes, when known
Pixel dimensions of the media, for images and videos
Width in pixels
Height in pixels
Aspect ratio (width / height)
Thumbnail of the media, when generated
chat\_ids of the participants mentioned in the message
Previous text content, kept when the message was edited. null when never edited.
Internal queue job id (queue\_id) that produced this message when it was sent through the message queue. null otherwise.
Per-recipient delivery and read receipts. null when no receipts have been recorded.
Map of recipient chat\_id to the epoch-millisecond timestamp the message was delivered to them
Map of recipient chat\_id to the epoch-millisecond timestamp they read the message
chat\_ids of recipients the message has not reached yet
Number of recipients the message was delivered to
Number of recipients who read the message
The poll definition (\{pollName, pollOptions, options}) for poll\_creation messages. null otherwise.
Votes cast on the poll, as a map of option name to voters. null for non-poll messages.
Whether the message is currently flagged for follow-up in Periskope. null when never flagged.
When the message record was last updated, as an ISO 8601 timestamp
Reactions placed on the message. Present on GET /message/\{message\_id}; an empty array when there are none.
Unique id of the reaction (a WhatsApp message\_id)
message\_id of the message the reaction belongs to
unique\_id of the message the reaction belongs to. null when not known.
Chat the reaction happened in
Id of the organization the reaction belongs to
Org phone (WhatsApp account) that observed the reaction, suffixed with @c.us
chat\_id of the person who reacted
The reaction emoji. An empty string or null means the reaction was removed.
Whether the reaction has been seen. null when unknown.
When the reaction happened, as an ISO 8601 timestamp
# The Note Object
Source: https://docs.periskope.app/api-reference/objects/the-note-object
A private note attached to a chat. Notes are internal to the workspace — they are never sent to WhatsApp and contacts cannot see them. Notes share the message record shape, so responses may include additional message fields (ack, sender_phone, sent_message_id, unique_id).
```json The Note Object theme={null}
{
"message_id": "true_00000000-0000-0000-0000-000000000000_api",
"org_id": "00000000-0000-0000-0000-000000000000",
"org_phone": "911111111111@c.us",
"chat_id": "120363000000000000@g.us",
"body": "Customer asked for a callback tomorrow @user@example.com",
"message_type": "chat",
"media": {
"path": "https://example.com/files/image.png",
"mimetype": "image/png",
"filename": "image.png"
},
"is_private_note": true,
"from_me": true,
"performed_by": "api",
"quoted_message_id": "true_00000000-0000-0000-0000-000000000000_api",
"mentioned_ids": [
"user@example.com"
],
"timestamp": "2026-01-15T09:30:00.000Z",
"updated_at": "2026-01-15T09:30:00.000Z"
}
```
**Attributes**
Unique id of the note, in the form true\_\\_\. Use this value as the note\_id path parameter when fetching a single note.
Id of the organization the note belongs to
Org phone (WhatsApp account) the note was created under, as country code + number suffixed with @c.us
Chat the note is attached to — \\@c.us for 1-1 chats, \@g.us for group chats
Text content of the note. null for media-only notes.
Content type of the note: 'chat' for text-only notes, otherwise the attachment type ('image', 'video', 'document' or 'audio')
Attachment details. null for text-only notes.
URL of the attachment — the url provided at creation, or the storage URL of the uploaded filedata
MIME type of the attachment
Filename of the attachment — the filename provided at creation, or one derived from the url
Always true — marks the record as a private note rather than a WhatsApp message One of: `true`.
Always true for notes — notes are authored by the org, never by the contact
Who created the note: the member's email, or "api" when created via the API
message\_id of the message or note this note replies to (set via reply\_to at creation). null when the note is not a reply.
Member emails @-mentioned in the note body. Each mention creates a task assigned to that member.
When the note was created, as an ISO 8601 UTC timestamp
When the note was last updated, as an ISO 8601 UTC timestamp
# The Phone Object
Source: https://docs.periskope.app/api-reference/objects/the-phone-object
A phone — a slot in the workspace that a WhatsApp account connects to by scanning a QR code. All phone-scoped endpoints act through one phone, selected with the x-phone header (org phone number or phone_id).
```json The Phone Object theme={null}
{
"phone_id": "phone-aaaaaaaaaaaa",
"org_id": "00000000-0000-0000-0000-000000000000",
"org_phone": "911111111111@c.us",
"phone_name": "Support",
"phone_image": "https://example.com/files/image.png",
"wa_state": "CONNECTED",
"is_ready": true,
"qr_code": null,
"label_ids": {
"label-aaaaaaaaaaaa": true
},
"labels": [
"support",
"priority"
],
"is_browser_open": true,
"last_disconnect": null,
"queue_status": null,
"first_connected_at": "2026-01-15T09:30:00.000Z",
"created_at": "2026-01-10T12:00:00.000Z",
"updated_at": "2026-01-15T09:30:00.000Z"
}
```
**Attributes**
Unique id of the phone (phone-xxxxxxxxxxxxxxxx). Accepted as the x-phone header value on phone-scoped endpoints.
Id of the organization the phone belongs to
WhatsApp number connected to the phone, as country code + number suffixed with @c.us. null until a WhatsApp account has been connected by scanning the QR.
Display name of the phone
URL of the profile image of the phone
WhatsApp connection state — 'CONNECTED' when the session is live, 'UNPAIRED'/'UNPAIRED\_IDLE' while awaiting a QR scan, other transient states include 'OPENING', 'PAIRING', 'TIMEOUT' and 'CONFLICT'. null before the phone has ever connected.
Whether the phone instance is booted and ready to send and receive messages
Raw QR payload while the phone is awaiting a QR scan; null once connected. Use GET /phones/qr to render it as a scannable image.
Labels assigned to the phone, keyed by label\_id (true = assigned)
Names of the labels assigned to the phone, resolved from label\_ids
Whether the phone's WhatsApp Web browser session is currently open
Details of the most recent disconnect event, if any. null when the phone has never disconnected.
Status of the phone's outgoing message queue, if any messages are queued
When a WhatsApp account was first connected to the phone, as an ISO 8601 timestamp. null if never connected.
When the phone was created, as an ISO 8601 timestamp
When the phone was last updated, as an ISO 8601 timestamp
# The Reaction Object
Source: https://docs.periskope.app/api-reference/objects/the-reaction-object
An emoji reaction on a WhatsApp message, synced from a connected org phone. Reactions reference the message they were applied to via message_id and carry who reacted (sender_id) and with which emoji (reaction).
```json The Reaction Object theme={null}
{
"reaction_id": "true_120363000000000000@g.us_AAAAAAAAAAAAAAAAAAAAAA_911111111111@c.us",
"org_id": "00000000-0000-0000-0000-000000000000",
"org_phone": "911111111111@c.us",
"chat_id": "120363000000000000@g.us",
"message_id": "false_120363000000000000@g.us_AAAAAAAAAAAAAAAAAAAA_922222222222@c.us",
"sender_id": "911111111111@c.us",
"reaction": "👍",
"timestamp": "2026-01-15T09:30:00+00:00",
"ack": 3,
"read": true,
"id": {
"id": "AAAAAAAAAAAAAAAAAAAAAA",
"fromMe": true,
"remote": "120363000000000000@g.us",
"_serialized": "true_120363000000000000@g.us_AAAAAAAAAAAAAAAAAAAAAA_911111111111@c.us",
"participant": "911111111111@c.us"
},
"msg_id": {
"id": "AAAAAAAAAAAAAAAAAAAAAA",
"fromMe": true,
"remote": "120363000000000000@g.us",
"_serialized": "true_120363000000000000@g.us_AAAAAAAAAAAAAAAAAAAAAA_911111111111@c.us",
"participant": "911111111111@c.us"
},
"unique_id": "AAAAAAAAAAAAAAAAAAAA",
"orphan": 0,
"orphan_reason": null
}
```
**Attributes**
Unique id of the reaction — the serialized WhatsApp id of the reaction event, in the form \*\*\\_\
Id of the organization the reaction belongs to
Org phone (WhatsApp account) the reaction was synced under, as country code + number suffixed with @c.us. Pass the x-phone header to scope results to one org phone.
Chat the reaction happened in — \@g.us for group chats, \\@c.us for 1-1 chats. Use it as the chat\_id query filter.
message\_id of the message that was reacted to, in the form \*\*\\_\. Use it as the message\_id query filter to fetch all reactions on one message.
WhatsApp id of who sent the reaction, as \\@c.us. This is the org phone itself when the reaction was sent from the connected phone.
The reaction emoji. Empty or null when the record carries no emoji (e.g. the sender removed their reaction).
When the reaction was sent, as an ISO 8601 timestamp. Reactions are ordered by this field (newest first) and filtered on it by start\_time/end\_time.
Delivery status of the reaction, tracked for reactions sent by the org phone: -1 failed, 0 pending, 1 sent to WhatsApp servers, 2 delivered to WhatsApp, 3 delivered to the recipient, 4 read, 5 played. null when not tracked.
Whether the reaction has been marked as read in Periskope. null when not tracked.
Raw WhatsApp id object of the reaction event itself. null when not available.
The WhatsApp message id — the unique id WhatsApp assigns to the message on the device
Whether the message was sent by the connected org phone (true) or received from a contact (false)
The chat the message belongs to — \@g.us for group chats, \\@c.us for 1-1 chats
The full serialized id, in the form \*\*\ with the sender appended in group chats
WhatsApp id of the sending participant within a group chat, as \\@c.us. Absent for 1-1 chats.
Raw WhatsApp id object of the message that was reacted to. null when not available.
The WhatsApp message id — the unique id WhatsApp assigns to the message on the device
Whether the message was sent by the connected org phone (true) or received from a contact (false)
The chat the message belongs to — \@g.us for group chats, \\@c.us for 1-1 chats
The full serialized id, in the form \*\*\ with the sender appended in group chats
WhatsApp id of the sending participant within a group chat, as \\@c.us. Absent for 1-1 chats.
The WhatsApp message id portion of the reacted-to message (msg\_id.id). null when not available.
Internal flag set by the WhatsApp sync pipeline. 0 or null for reactions that synced normally.
Internal reason recorded by the sync pipeline when orphan is set. null for reactions that synced normally.
# The Task Object
Source: https://docs.periskope.app/api-reference/objects/the-task-object
A task in the workspace. Tasks are either standalone to-dos (type: todo) or linked to a chat, message or ticket via association. Tasks belong to the workspace as a whole, not to a specific phone.
```json The Task Object theme={null}
{
"task_id": "task-aaaaaaaaaaaa",
"title": "Call back the customer about the renewal quote",
"type": "message",
"status": "open",
"priority": 2,
"assignee": "user@example.com",
"created_by": "api",
"last_updated_by": "api",
"created_at": "2026-01-15T09:30:00.000Z",
"last_updated_at": "2026-01-15T09:30:00.000Z",
"due_date": "2026-01-20T17:00:00.000Z",
"remind_at": "2026-01-20T09:00:00.000Z",
"notes": "Customer prefers a call after 3pm IST",
"chat_id": "120363000000000000@g.us",
"association": {
"type": "message",
"chat_id": "120363000000000000@g.us",
"message_id": "false_120363000000000000@g.us_AAAAAAAAAAAAAAAAAAAA",
"ticket_id": "ACM-042"
},
"completed_metadata": {
"completed_at": "2026-01-21T10:15:00.000Z",
"completed_by": "user@example.com"
}
}
```
**Attributes**
Unique id of the task (task-xxxxxxxxxxxxxxxx). Use this value as the task\_id path parameter when fetching or updating the task.
Title of the task, up to 500 characters
Kind of task: 'todo' for a standalone task, or 'chat', 'message' or 'ticket' for a task linked to that object. Immutable after creation. One of: `todo`, `chat`, `message`, `ticket`.
Lifecycle status of the task: 'open', 'inprogress' or 'closed' One of: `open`, `inprogress`, `closed`.
Priority of the task: 1 (low), 2 (medium) or 3 (high)
Email of the workspace member the task is assigned to. null when the task is unassigned.
Who created the task: a member's email, or "api" when created via the API without a created\_by
Who last changed the task: a member's email, or "api" for API changes without a last\_updated\_by
When the task was created, as an ISO 8601 timestamp
When the task was last updated, as an ISO 8601 timestamp
When the task is due, as an ISO 8601 UTC timestamp. null when no due date is set.
When a reminder for the task fires, as an ISO 8601 UTC timestamp. null when no reminder is set.
Free-form notes on the task. null when none were set.
Id of the chat the task is linked to (directly, or through its message or ticket). null for todo tasks.
The chat, message or ticket the task is linked to. null for todo tasks.
Kind of object the task is linked to: 'chat', 'message' or 'ticket'. Mirrors the task's type. One of: `chat`, `message`, `ticket`.
Id of the chat the linked object belongs to — \\@c.us for 1-1 chats, \@g.us for group chats. Present for every association kind; the chat itself for chat tasks, the chat of the message or ticket otherwise. null when the chat could not be resolved.
message\_id of the linked message. Present only when type is 'message'.
ticket\_id of the linked ticket. Present only when type is 'ticket'.
Completion details, recorded when the task moves to status 'closed' and cleared when it is reopened. null while the task is open or inprogress.
When the task was closed, as an ISO 8601 timestamp
Who closed the task: a member's email, or "api" for API changes without an actor
# The Ticket Info Object
Source: https://docs.periskope.app/api-reference/objects/the-ticket-info-object
A ticket together with its chat, the message it was raised from and (on GET /tickets/{ticket_id}) the messages attached to it.
```json The Ticket Info Object theme={null}
{
"chat": {
"org_id": "00000000-0000-0000-0000-000000000000",
"chat_id": "120363000000000000@g.us",
"members": {
"key": {
"contact_id": "911111111111@c.us",
"chat_id": "120363000000000000@g.us",
"org_id": "00000000-0000-0000-0000-000000000000",
"org_phone": "911111111111@c.us",
"is_admin": false,
"is_super_admin": false,
"contact_name": "Rahul Sharma",
"contact_image": "https://example.com/files/image.png",
"contact_color": "#7D9EF1",
"is_internal": false,
"contact_labels": "vip, billing"
}
},
"is_muted": false,
"chat_name": "Example Corp Support",
"chat_type": "group",
"org_phone": "911111111111@c.us",
"chat_image": "https://example.com/files/image.png",
"created_at": "2026-01-10T08:00:00+00:00",
"chat_labels": "customer, priority",
"invite_link": null,
"group_description": null,
"custom_properties": {
"Region": "EMEA"
},
"freshdesk_metadata": {},
"zohodesk_metadata": {},
"initiated_by": null,
"is_archived": false,
"parent_community_id": null
},
"message": {
"message_id": "false_120363000000000000@g.us_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"chat_id": "120363000000000000@g.us",
"org_phone": "911111111111@c.us",
"timestamp": "2026-01-15T09:28:00+00:00",
"body": "I cannot open my invoices from the portal",
"media_path": "",
"sender_phone": "911111111111",
"sender_name": "Rahul Sharma",
"performed_by": null
},
"ticket": {
"ticket_id": "ACM-001",
"org_id": "00000000-0000-0000-0000-000000000000",
"subject": "Customer cannot access invoices",
"status": "open",
"priority": 2,
"assignee": "user@example.com",
"assigned_by": "",
"raised_by": "api",
"due_date": "2026-02-01 00:00:00+00",
"ticket_labels": "urgent, billing",
"ticket_custom_properties": {
"Workspace": "Example Corp"
},
"quoted_message_id": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"created_at": "2026-01-15T09:30:00.000Z",
"closed_at": null,
"closed_by": null,
"closed_message": null,
"first_assigned_at": null,
"is_deleted": false
},
"attached_messages": [
{
"message_id": "false_120363000000000000@g.us_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"chat_id": "120363000000000000@g.us",
"org_phone": "911111111111@c.us",
"timestamp": "2026-01-15T09:28:00+00:00",
"body": "I cannot open my invoices from the portal",
"media_path": "",
"sender_phone": "911111111111",
"sender_name": "Rahul Sharma",
"performed_by": null
}
]
}
```
**Attributes**
The chat the ticket is raised on. null in the rare case the chat record is no longer available.
Id of the organization the chat belongs to
Unique id of the chat — \\@c.us for 1-1 chats, \@g.us for group chats
Participants of the chat, as a map of contact\_id → member. null when no participants are recorded.
Contact id of the member, suffixed with @c.us
Chat the membership belongs to
Id of the organization
Org phone (WhatsApp account) the chat belongs to, suffixed with @c.us
Whether the member is an admin of the group chat
Whether the member is the super admin (creator) of the group chat
Saved name of the contact. null when not a saved contact.
URL of the profile image of the contact, when available
Hex color assigned to the contact in the dashboard
Whether the contact is an internal (workspace) contact rather than an external customer
Names of the labels applied to the contact, joined with ", ". An empty string when the contact has no labels.
Whether the chat is muted on the phone
Display name of the chat
Type of the chat: 'user' for 1-1 chats, 'group' for groups
Org phone (WhatsApp account) the chat belongs to, suffixed with @c.us
URL of the chat image, when available
When the chat was created, as an ISO 8601 timestamp
Names of the labels applied to the chat, joined with ", ". An empty string when the chat has no labels.
WhatsApp invite link of the group. null for 1-1 chats or when not available.
Description of the group. null for 1-1 chats.
Values of every chat custom property of the workspace, as a map of property name → formatted display value (an empty string for properties not set on this chat). Property definitions are managed via the Properties endpoints (see the CustomProperty component).
Sync metadata of the Freshdesk integration, when connected
Sync metadata of the Zoho Desk integration, when connected
Who initiated the chat, when known (e.g. the org phone or the contact)
Whether the chat is archived on the phone
Id of the parent WhatsApp community when the group belongs to one. null otherwise.
The message the ticket was raised from (quoted\_message\_id). Always present as an object — every field in it is null when the ticket is not linked to a message.
Unique id of the message. Like every field of this object, null when the ticket has no linked message.
Chat the message belongs to
Org phone (WhatsApp account) the message was sent or received on, suffixed with @c.us
When the message was sent, as an ISO 8601 timestamp
Text content of the message. An empty string for media-only messages.
URL of the message attachment. An empty string when the message has no media.
Phone number of the sender, as country code + number without the @c.us suffix
Contact name of the sender. An empty string when the sender is not a saved contact.
Who sent the message through Periskope: a member's email or 'api'. null for messages received from WhatsApp.
The ticket itself
Unique human-readable id of the ticket
Id of the organization the ticket belongs to
Subject of the ticket
Lifecycle status of the ticket: 'open', 'inprogress', 'closed' or 'archived' One of: `open`, `inprogress`, `closed`, `archived`.
Priority of the ticket: 1 (low), 2 (medium), 3 (high) or 4 (urgent). Tickets with no priority set are reported as 1 here.
Email of the member the ticket is assigned to. An empty string when unassigned.
Email of the member who assigned the ticket. An empty string when it has not been assigned.
Who raised the ticket: a member's email, or 'api' when created via the API
Due date of the ticket as a timestamp string (e.g. 2026-02-01 00:00:00+00). An empty string when no due date is set.
Names of the ticket labels applied to the ticket, joined with ", ". An empty string when the ticket has no labels.
Values of every ticket custom property of the workspace, as a map of property name → formatted display value (an empty string for properties not set on this ticket; option ids are resolved to their labels). Property definitions are managed via the Properties endpoints (see the CustomProperty component).
Unique id of the message the ticket was raised from. null when the ticket is not linked to a message.
When the ticket was created, as an ISO 8601 timestamp
When the ticket was closed, as an ISO 8601 timestamp. null while the ticket is not closed.
Who closed the ticket: a member's email, or 'api' when closed via the API without a closed\_by value. null while the ticket is not closed.
Closing message supplied when the ticket was closed. null while the ticket is not closed or when none was given.
When the ticket was first assigned to a member, as an ISO 8601 timestamp. null when it has never been assigned.
Whether the ticket has been deleted
Messages attached to the ticket. Populated only by GET /tickets/\{ticket\_id} — always an empty array in create and update responses.
Unique id of the message. Like every field of this object, null when the ticket has no linked message.
Chat the message belongs to
Org phone (WhatsApp account) the message was sent or received on, suffixed with @c.us
When the message was sent, as an ISO 8601 timestamp
Text content of the message. An empty string for media-only messages.
URL of the message attachment. An empty string when the message has no media.
Phone number of the sender, as country code + number without the @c.us suffix
Contact name of the sender. An empty string when the sender is not a saved contact.
Who sent the message through Periskope: a member's email or 'api'. null for messages received from WhatsApp.
# Create Phone
Source: https://docs.periskope.app/api-reference/phones/create-phone
api-reference/openapi-generated.json POST /v1/phones/create
Creates a new phone in the workspace and boots its instance. Do not send an x-phone header.
# Delete Phone
Source: https://docs.periskope.app/api-reference/phones/delete-phone
api-reference/openapi-generated.json DELETE /v1/phones/delete
Permanently deletes the phone and tears down its instance. Cannot be undone.
# Get All Phones
Source: https://docs.periskope.app/api-reference/phones/get-all-phones
api-reference/openapi-generated.json GET /v1/phones/all
Returns every phone the API token can access. No x-phone header needed.
# Get phone
Source: https://docs.periskope.app/api-reference/phones/get-phone
api-reference/openapi-generated.json GET /v1/phones
Returns the phone in the x-phone header, refreshing its state from the live instance when reachable.
# Get QR
Source: https://docs.periskope.app/api-reference/phones/get-qr
api-reference/openapi-generated.json GET /v1/phones/qr
Returns the QR code of the phone as an HTML page with an inline PNG. Scan it with WhatsApp (Settings > Linked Devices) to connect.
# Reset Phone
Source: https://docs.periskope.app/api-reference/phones/reset-phone
api-reference/openapi-generated.json POST /v1/phones/reset
Logs out the WhatsApp session and resets the phone to the QR state — rescan via GET /phones/qr to reconnect.
# Restart Phone
Source: https://docs.periskope.app/api-reference/phones/restart-phone
api-reference/openapi-generated.json POST /v1/phones/restart
Restarts the instance of the phone — works even while the phone server is switched off.
# Resync Phone
Source: https://docs.periskope.app/api-reference/phones/resync-phone
api-reference/openapi-generated.json POST /v1/phones/resync
Triggers a full resync between WhatsApp and Periskope for the phone. The phone must be connected.
# Update phone
Source: https://docs.periskope.app/api-reference/phones/update-phone
api-reference/openapi-generated.json PATCH /v1/phones/update
Updates the display name, profile image and/or labels of the phone. Name and image changes are pushed to WhatsApp.
# Create Custom Property
Source: https://docs.periskope.app/api-reference/properties/create-custom-property
api-reference/openapi-generated.json POST /v1/properties/create
Creates a custom property for chats or tickets. Options apply to dropdown and picklist kinds.
# Delete Custom Properties
Source: https://docs.periskope.app/api-reference/properties/delete-custom-property
api-reference/openapi-generated.json DELETE /v1/properties
Deletes one or more custom properties, by property_ids or names, via ticket_properties and/or chat_properties.
# Get All Custom Properties
Source: https://docs.periskope.app/api-reference/properties/get-all-custom-properties
api-reference/openapi-generated.json GET /v1/properties
Returns every custom property (chat and ticket), including dropdown and picklist options. Filter with the type query param.
# Get Custom Property
Source: https://docs.periskope.app/api-reference/properties/get-custom-property
api-reference/openapi-generated.json GET /v1/properties/{property_id}
Looks up a custom property by property_id or name (case-insensitive), including its options.
# Update Custom Property
Source: https://docs.periskope.app/api-reference/properties/update-custom-property
api-reference/openapi-generated.json POST /v1/properties/{property_id}
Updates the name, section and/or mandatory flag of a custom property — at least one is required.
# Update Property Options
Source: https://docs.periskope.app/api-reference/properties/update-property-options
api-reference/openapi-generated.json POST /v1/properties/{property_id}/options
Adds or removes options on a dropdown or picklist property. Adding is idempotent on the label (case-insensitive).
# Fetch Queue Jobs
Source: https://docs.periskope.app/api-reference/queues/fetch-queue-jobs
api-reference/openapi-generated.json GET /v1/queue/jobs
Lists the jobs in the send queue of the phone — scheduled, waiting, in flight, completed or failed.
**Deprecated.** Use [`POST /message/queues`](/api-reference/message/list-queue-jobs) instead.
Pass `queue_id` or `broadcast_id` in the request body to filter
# Get Broadcast Status
Source: https://docs.periskope.app/api-reference/queues/get-broadcast-status
api-reference/openapi-generated.json GET /v1/queue/broadcast
Returns the aggregate delivery status of a broadcast: sent, failed and pending counts, delivered/read percentages, and scheduling info.
**Deprecated.** Use [`POST /message/queues`](/api-reference/message/list-queue-jobs) with `broadcast_id` in the request body instead
# Get Queue Status
Source: https://docs.periskope.app/api-reference/queues/get-queue-status
api-reference/openapi-generated.json GET /v1/queue
Returns the live status of the message send queue of the phone in the x-phone header.
**Deprecated.** Use [`GET /message/queues/health`](/api-reference/message/queue-health) instead
# Purge Queue
Source: https://docs.periskope.app/api-reference/queues/purge-queue
api-reference/openapi-generated.json DELETE /v1/queue/purge
Removes jobs from the send queue by queue_id or broadcast_id. Warning: an omitted or empty body purges the ENTIRE queue. Messages already submitted to WhatsApp are unaffected.
**Deprecated.** Use [`POST /message/queues/purge`](/api-reference/message/purge-queue-jobs) instead.
The request body shape is the same, `queue_ids` and `broadcast_id` are accepted
# Get Reactions
Source: https://docs.periskope.app/api-reference/reactions/get-reactions
api-reference/openapi-generated.json GET /v1/reactions
Returns emoji reactions across the workspace, newest first. Filter by chat_id and/or message_id.
# Delete Scheduled Message
Source: https://docs.periskope.app/api-reference/scheduled-messages/delete-scheduled-message
api-reference/openapi-generated.json DELETE /v1/message/scheduled/{scheduled_id}
Permanently deletes a scheduled message — no further runs happen. Its run history stays available via the occurrences endpoint.
# Get Scheduled Message
Source: https://docs.periskope.app/api-reference/scheduled-messages/get-scheduled-message
api-reference/openapi-generated.json GET /v1/message/scheduled/{scheduled_id}
Retrieves a scheduled message by its scheduled_id.
# List Scheduled Message Runs
Source: https://docs.periskope.app/api-reference/scheduled-messages/list-scheduled-message-occurrences
api-reference/openapi-generated.json GET /v1/message/scheduled/{scheduled_id}/occurrences
Returns the run history of a scheduled message, newest first — each run records whether it sent, failed or was skipped, and the resulting message id.
# List Scheduled Messages
Source: https://docs.periskope.app/api-reference/scheduled-messages/list-scheduled-messages
api-reference/openapi-generated.json GET /v1/message/scheduled
Returns the scheduled messages of the workspace, by next run time. Filter by chat, creator, status and repetition, search the message text, and restrict to a scheduled_at window.
# Schedule a Message
Source: https://docs.periskope.app/api-reference/scheduled-messages/schedule-message
api-reference/openapi-generated.json POST /v1/message/scheduled
Schedules a message (text and/or media) to be sent to a chat from the phone in the x-phone header at scheduled_at — once, or repeating per repeat_config. The send itself happens in the background at run time.
# Update Scheduled Message
Source: https://docs.periskope.app/api-reference/scheduled-messages/update-scheduled-message
api-reference/openapi-generated.json PATCH /v1/message/scheduled/{scheduled_id}
Updates a pending scheduled message — content, next run time, repetition, pause/resume or skip-next. Completed messages cannot be updated.
# SDK
Source: https://docs.periskope.app/api-reference/sdk
Build with Periskope using our Typescript SDK
The Periskope Typescript client exposes our [RESTful APIs](/api-reference/introduction) with complete type-safety, semantically named functions, and straightforward JSON responses. Whether you're building bots, automating customer support, sending messages, managing tickets, or creating groups, Periskope Client makes it quick and efficient to integrate Periskope into your workflow.
We encourage responsible usage of the APIs. Follow these best practices and recommendations for safe actions on WhatsApp - [https://docs.periskope.app/get-started/best-practices](https://docs.periskope.app/get-started/best-practices)
## Prerequisites
1. **Sign up for a free account on Periskope**: To use the Periskope Client, you need to have an active Periskope account. If you don't have one, you can sign up for a 7-day free trial [here](https://console.periskope.app).
2. **Scan the QR code from WhatsApp to connect your phone**: A connected phone is required to use the package
3. **Generate an API Key**: An API key is required for authentication and can be generated from your Periskope settings [here](https://console.periskope.app/settings/integrations/api).
## Setup Guide
If you don't already have Node.js installed, download it from the [official Node.js website](https://nodejs.org/).\
We recommend installing the **LTS version** for better stability.
You can verify your installation by running:
```bash theme={null}
node -v
npm -v
```
Use your preferred package manager to install the official Periskope client:
```bash theme={null}
npm install @periskope/periskope-client
# or
yarn add @periskope/periskope-client
```
Here's a basic example of how to use the Periskope client in your code:
```js theme={null}
import { PeriskopeApi } from "@periskope/periskope-client";
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
async function sendMessage() {
try {
const response = await client.messages.sendMessage({
chat_id: 'RECEPIENT_PHONE_NUMBER',
message:"Hello from Periskope"
});
console.log('Message sent:', response);
} catch (error) {
console.error('Failed to send message:', error);
}
}
sendMessage();
```
That's it! You've set up Node.js, installed the Periskope client SDK, and made your first API call using JavaScript or Typescript.\
You can now explore more features like creating groups, raising tickets, and listening to webhooks.
## Webhooks
Periskope emits various webhook events that you can listen to in real-time using the SDK. These events allow your application to respond automatically to activities like incoming messages, status changes, and other WhatsApp interactions. For a comprehensive overview of all webhook events and their payloads, check out our [Webhooks](/api-reference/webhooks/introduction) docs.
The SDK provides an event emitter interface that makes it easy to subscribe to these events without setting up a separate webhook server.
#### Usage
Here's a basic example of how to subscribe to the **message.created** event using the Typescript package:
```js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.connect(); // First connect the socket
client.on('message.created', (data) => {
console.log(data);
// Handle new messages here - respond, process commands, update your database, etc.
});
```
### Available Webhook Events
The SDK supports listening to various event types including:
* `chat.created` - Triggered when a new chat is created [🔗](/api-reference/webhooks/chat.created)
* `chat.notification.created` - Triggered when a new chat notification is created [🔗](/api-reference/webhooks/chat.notification.created)
* `chat.custom_properties.updated` - Triggered when chat custom properties are updated [🔗](/api-reference/webhooks/chat.custom-properties.updated)
* `message.created` - Triggered when a new message is received or sent [🔗](/api-reference/webhooks/message.created)
* `message.updated` - Triggered when message is edited [🔗](/api-reference/webhooks/message.updated)
* `message.deleted` - Triggered when message is deleted [🔗](/api-reference/webhooks/message.deleted)
* `message.ack.updated` - Triggered when a message is acknowledged [🔗](/api-reference/webhooks/message.ack.updated)
* `message.ticket.attached` - Triggered when a message is attached to a ticket [🔗](/api-reference/webhooks/message.ticket.attached)
* `message.flagged` - Triggered when a message is flagged [🔗](/api-reference/webhooks/message.flagged)
* `message.unflagged` - Triggered when a message is unflagged [🔗](/api-reference/webhooks/message.unflagged)
* `reaction.created` - Triggered when a reaction is created [🔗](/api-reference/webhooks/reaction.created)
* `reaction.updated` - Triggered when a reaction is updated [🔗](/api-reference/webhooks/reaction.updated)
* `ticket.created` - Triggered when a new ticket is created [🔗](/api-reference/webhooks/ticket.created)
* `ticket.updated` - Triggered when a ticket details are updated [🔗](/api-reference/webhooks/ticket.updated)
* `ticket.deleted` - Triggered when a ticket is deleted [🔗](/api-reference/webhooks/ticket.deleted)
* `org.phone.updated` - Triggered when a phone number, phone name or phone image changes [🔗](/api-reference/webhooks/org.phone.updated)
* `org.phone.connected` - Triggered when a phone changes to a connected state [🔗](/api-reference/webhooks/org.phone.updated)
* `org.phone.disconnected` - Triggered when a phone changes to a disconnected state [🔗](/api-reference/webhooks/org.phone.updated)
* `org.phone.qr` - Triggered when a phone's QR code changes [🔗](/api-reference/webhooks/org.phone.updated)
### Implementing Event Handlers
You can implement multiple event handlers to build comprehensive automations:
```js theme={null}
// Listen for new messages
client.on('message.created', async (messageData) => {
if (messageData.body && messageData.body.toLowerCase().includes('help')) {
// Respond to help requests automatically
await client.messages.sendMessage({
chat_id: messageData.chat.id,
message: "Here's how I can help you...",
});
}
});
// Listen for ticket updates
client.on('ticket.updated', (ticketData) => {
if (ticketData.ticket.status === 'closed') {
// Perform actions when tickets are closed
console.log(`Ticket #${ticketData.id} has been resolved`);
}
});
```
# Create Task
Source: https://docs.periskope.app/api-reference/tasks/create-task
api-reference/openapi-generated.json POST /v1/tasks/create
Creates a task — standalone (type: todo, default) or linked to a chat, message or ticket via type and the matching id.
# Get Task By ID
Source: https://docs.periskope.app/api-reference/tasks/get-task-by-id
api-reference/openapi-generated.json GET /v1/tasks/{task_id}
Looks up a task by its task_id. Responds 404 when no task matches.
# Get All Tasks
Source: https://docs.periskope.app/api-reference/tasks/get-tasks
api-reference/openapi-generated.json GET /v1/tasks
Returns the tasks of the workspace, newest first, across every task kind.
# Update Task
Source: https://docs.periskope.app/api-reference/tasks/update-task
api-reference/openapi-generated.json PATCH /v1/tasks/{task_id}
Updates a task — any combination of title, status, priority, assignee, due_date, notes and remind_at; at least one required. The type and associations cannot change.
# Create Ticket
Source: https://docs.periskope.app/api-reference/tickets/create-ticket
api-reference/openapi-generated.json POST /v1/tickets/create
Creates a ticket on a chat (chat_id and subject required). Only one ticket can be raised per message. Custom property values cannot be set at creation — use the update endpoint after.
# Get Ticket Audit Logs
Source: https://docs.periskope.app/api-reference/tickets/get-ticket-audit-logs
api-reference/openapi-generated.json GET /v1/tickets/{ticket_id}/audit-logs
Returns the audit trail of a ticket — who changed what and when — newest first. Filter by performed_by and action, and restrict to a timestamp window.
# Get Ticket By ID
Source: https://docs.periskope.app/api-reference/tickets/get-ticket-by-id
api-reference/openapi-generated.json GET /v1/tickets/{ticket_id}
Looks up a ticket by its ticket_id, together with its chat and the message it was raised from.
# Get Tickets
Source: https://docs.periskope.app/api-reference/tickets/get-tickets
api-reference/openapi-generated.json GET /v1/tickets
Returns the tickets of the workspace, newest first, excluding deleted tickets.
# Update Ticket
Source: https://docs.periskope.app/api-reference/tickets/update-ticket
api-reference/openapi-generated.json PATCH /v1/tickets/{ticket_id}
Updates a ticket — any combination of the body fields, at least one required. labels replaces the entire label set.
# chat.created
Source: https://docs.periskope.app/api-reference/webhooks/chat.created
The `chat.created` webhook is triggered when a new group or individual chat is created on whatsapp.
Refer [Chat](/api-reference/objects/the-chat-object) object to find more details about `chat object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('chat.created', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# chat.custom-properties.updated
Source: https://docs.periskope.app/api-reference/webhooks/chat.custom-properties.updated
The `chat.custom_properties.updated` webhook is triggered when a new group or individual chat is created on WhatsApp.
Refer [Chat](/api-reference/objects/the-chat-object) object to find more details about `chat object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('chat.custom_properties.updated', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# chat.notification.created
Source: https://docs.periskope.app/api-reference/webhooks/chat.notification.created
The `chat.notification.created` webhook is triggered when any action is performed on a chat. For e.g. when a member is added or removed from a chat, when group settings is updated.
```json The Chat Notification Object theme={null}
{
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"notification_id": "true_120363371308389685@g.us_fa3c48a78cc64e139e5737f7057235ea_918527184400@c.us_remove",
"chat_id": "120363371308389685@g.us",
"author": "918527184400@c.us",
"body": null,
"id": {
"id": "fa3c48a78cc64e139e5737f7057235ea",
"fromMe": true,
"remote": "120363371308389685@g.us",
"serialized": "true_120363371308389685@g.us_fa3c48a78cc64e139e5737f7057235ea_918527184400@c.us_remove"
},
"recipientids": [
"919537851844@c.us"
],
"type": "remove",
"timestamp": "2025-01-11T11:52:27.231+00:00",
"org_phone": "918527184400@c.us",
"unique_id": "fa3c48a78cc64e139e5737f7057235ea",
"metadata": null
}
```
Refer [Chat Notification](/api-reference/objects/the-chat-notification-object) object to find more details about `chat notification object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('chat.notification.created', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# Create Webhook
Source: https://docs.periskope.app/api-reference/webhooks/create-webhook
api-reference/openapi-generated.json POST /v1/webhooks
Subscribes an endpoint URL to one or more event types — one subscription row per event type, sharing an integration_id.
# Delete Webhook
Source: https://docs.periskope.app/api-reference/webhooks/delete-webhook
api-reference/openapi-generated.json DELETE /v1/webhooks/{id}
Permanently deletes a webhook subscription row by id. Its sibling rows (same create call) are marked unsubscribed — to pause without deleting, use PATCH with isSubscribed: false.
# Get Webhook by ID
Source: https://docs.periskope.app/api-reference/webhooks/get-webhook-by-id
api-reference/openapi-generated.json GET /v1/webhooks/{id}
Looks up a webhook subscription row by its id.
# Introduction
Source: https://docs.periskope.app/api-reference/webhooks/introduction
Listen to events on Periskope and build your custom integrations
While building your own WhatsApp integrations with Periskope, you might want to listen to events in real time. You can do this with Periskope's Webhooks.
Simply register a Webhook endpoint with Periskope and start receiving different events occuring inside the Periskope platform.
You can also receive events with our [Typescript SDK](/api-reference/sdk)
## Prerequisites
1. A `Periskope account`: To use the Periskope API, you need to have a Periskope account. If you don't have one, you can sign up for a free trial [here](https://console.periskope.app).
2. An `HTTP POST /` Endpoint: Prepare your server to start receiving POST requests. Your server should have an endpoint ready to catch data sent by Periskope when events are sent.
In order to start receiving webhooks, you need to have a server that can handle incoming HTTP POST requests. The POST request endpoint needs to be open and publicly accessible without any authentication.
## Setting up webhooks on Periskope 🔧
You can access the webhook configuration through your Periskope settings or click [here](https://console.periskope.app/settings/integrations/webhooks) to visit. Here, you can manage and set up new webhooks.
Click on the `Add Webhook` button. This opens a modal where you can enter
the URL that will receive the webhook POST requests.
Choose the events you want to subscribe to from the list below. Each event
corresponds to different actions or changes in Periskope and whatsapp that
you can receive notifications for.
Signing Keys are used to verify that the webhook events that you receive on your destination come from a trusted source.
You can generate a Signing Key on the Webhook Screen by clicking on the `Generate` button. After copying your Signing Key, do not
share it to keep it protected. Learn more about how to verify your Signing Key on your server here.
After configuring the URL and selecting the desired events, save your
settings to activate the webhook.
## Result 🚀
Webhooks are now setted up on your Periskope account. Your endpoint will now receive HTTP POST requests whenever the subscribed events occur on the Periskope platform.
You can test your webhook by triggering any selected event from the Periskope platform.
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
## Verifying your Signing Key
A signing key is used to verify that the events received in your webhook endpoints are from a trusted source. Periskope generates an
encrypted HMAC key for every request and sends the key in the `x-periskope-signature` header. On your webhook endpoint, you can check
this signature by decrypting the secret key and verifying the legitimacy of a request.
You can generate your Singing Key from `Settings > Webhooks` screen.
Follow the code snippet below to verify your signing key on your server:
```typescript theme={null}
import * as express from "express";
import { createHmac } from "crypto";
// Replace this with your actual signing key obtained from the Periskope dashboard (to be stored in .env)
const SHARED_SECRET = "YOUR_SIGNING_SECRET";
const app = express();
app.use(express.json());
// Verification function to check the signature of the request
function verifySignature(rawBody: Record, signature: string) {
// Create an HMAC SHA256 hash using the shared secret key
const hmac = createHmac("sha256", SHARED_SECRET);
// Update the HMAC hash with the stringified payload
hmac.update(JSON.stringify(rawBody));
// Calculate the HMAC digest in hexadecimal format
const digest = hmac.digest("hex");
// Compare the calculated digest with the signature provided in the header
return digest === signature;
}
// Webhook endpoint handler for POST requests to /webhook
app.post("/webhook", (req: express.Request, res: express.Response) => {
// Extract the signature from the 'x-periskope-signature' header
const signature = req.headers["x-periskope-signature"] as string;
// Verify the signature of the incoming request.
// It's important to use the raw request body before any parsing/modification
// if your framework modifies the body.
// Here, we assume `req.body` contains the parsed JSON object.
const isValid = verifySignature(req.body, signature);
// If the signature is invalid, respond with an Unauthorized status
if (!isValid) {
return res.status(401).send("Invalid signature");
}
// If the signature is valid, process the webhook event
console.log("Received valid webhook event:", req.body);
// Add your custom logic here to handle the event (e.g., update database, send notifications)
res.status(200).send("ok");
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Webhook server listening on port ${PORT}`);
});
```
# List Webhooks
Source: https://docs.periskope.app/api-reference/webhooks/list-webhooks
api-reference/openapi-generated.json GET /v1/webhooks
Returns the webhook subscriptions of the workspace, newest first. One row exists per subscribed event type.
# message.ack.updated
Source: https://docs.periskope.app/api-reference/webhooks/message.ack.updated
The `message.ack.updated` webhook is triggered when a new message is received or sent on whatsapp.
```json The Message Object theme={null}
{
"message_id": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us",
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"ack": "2",
"author": "9190043XXXXX@c.us",
"body": "Hello, world",
"broadcast": null,
"device_type": "android",
"flag_status": false,
"duration": null,
"forwarding_score": "0",
"from": "9190043XXXXX@c.us",
"from_me": true,
"has_media": true,
"has_quoted_msg": false,
"has_reaction": false,
"id": {
"id": "3EB01F4653XX9XX05E9859",
"fromMe": true,
"remote": "12036329726967XXXX@g.us",
"_serialized": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us"
},
"invite_v4": null,
"is_ephemeral": null, //disappearing messages
"is_forwarded": false,
"is_gif": false,
"is_starred": false,
"is_status": false,
"links": "[]",
"location": null,
"media_key": null,
"mentioned_ids": [],
"order_id": null,
"raw_data": null,
"to": "12036329726967XXXX@g.us",
"token": null,
"message_type": "image",
"vcards": [],
"chat_id": "12036329726967XXXX@g.us",
"timestamp": "2024-05-13 11:19:34+00",
"org_phone": "9190043XXXXX@c.us",
"broadcast_id": null,
"is_deleted": null,
"media": {
"path": "/storage/v1/object/public/message-media/2997xx64-89bf-48d3-9a22-b314fxx017e5/12036329726967XXXX@g.us/true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us/dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"size": 19940,
"filename": "dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"mimetype": "image/jpeg",
"dimensions": {
"ar": 1,
"width": 512,
"height": 512
}
},
"performed_by": "harsh.gour@hashlabs.dev",
"prev_body": null,
"quoted_message_id": null,
"sender_phone": "9190043XXXXX@c.us",
"sent_message_id": "f7b10126-5d5e-432f-941c-94ced28debac",
"delivery_info": {
"read": {
"919XXXXXXXXXXX@c.us": 1731984657443
},
"pending": [
"9184XXXXXXXXXX@c.us",
"919XXXXXXXXXXX@c.us"
],
"delivered": {
"919XXXXXXXXXXX@c.us": 1731214159000,
"919XXXXXXXXXXX@c.us": 1731195010000,
"919XXXXXXXXXXX@c.us": 1731175846000,
"919XXXXXXXXXXX@c.us": 1731175848000,
"919XXXXXXXXXXX@c.us": 1731175847000
},
"read_count": 0,
"delivered_count": 5
},
"flag_metadata": {
"status": false,
"response_id": "3A1AXXXXXXXXXX",
"response_type": "message",
"response_email": "91XXXXXXXXX@c.us",
"response_timestamp": "2024-11-26T15:16:32.179Z"
},
"poll_info": {
"options": {
"allowMultipleAnswers": true
},
"pollName": "pollQuestion",
"pollOptions": [
"option1",
"option2",
"option3"
]
},
"poll_results": {
"option1": {
"91903XXXXXX0@c.us": "2024-05-24T15:24:11.336Z"
},
"option2": {},
"option3": {}
},
"interactive": null,
"updated_at": "2024-05-13 11:19:36.114+00",
"message_ticket_id": null,
"unique_id": "3EB01F4653XX9XX05E9859"
}
```
Refer [Message](/api-reference/objects/the-message-object) object to find more details about `message object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('message.ack.updated', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# message.created
Source: https://docs.periskope.app/api-reference/webhooks/message.created
The `message.created` webhook is triggered when a new message is received or sent on whatsapp.
```json The Message Object theme={null}
{
"message_id": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us",
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"ack": "2",
"author": "9190043XXXXX@c.us",
"body": "Hello, world",
"broadcast": null,
"device_type": "android",
"flag_status": false,
"duration": null,
"forwarding_score": "0",
"from": "9190043XXXXX@c.us",
"from_me": true,
"has_media": true,
"has_quoted_msg": false,
"has_reaction": false,
"id": {
"id": "3EB01F4653XX9XX05E9859",
"fromMe": true,
"remote": "12036329726967XXXX@g.us",
"_serialized": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us"
},
"invite_v4": null,
"is_ephemeral": null, //disappearing messages
"is_forwarded": false,
"is_gif": false,
"is_starred": false,
"is_status": false,
"links": "[]",
"location": null,
"media_key": null,
"mentioned_ids": [],
"order_id": null,
"raw_data": null,
"to": "12036329726967XXXX@g.us",
"token": null,
"message_type": "image",
"vcards": [],
"chat_id": "12036329726967XXXX@g.us",
"timestamp": "2024-05-13 11:19:34+00",
"org_phone": "9190043XXXXX@c.us",
"broadcast_id": null,
"is_deleted": null,
"media": {
"path": "/storage/v1/object/public/message-media/2997xx64-89bf-48d3-9a22-b314fxx017e5/12036329726967XXXX@g.us/true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us/dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"size": 19940,
"filename": "dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"mimetype": "image/jpeg",
"dimensions": {
"ar": 1,
"width": 512,
"height": 512
}
},
"performed_by": "harsh.gour@hashlabs.dev",
"prev_body": null,
"quoted_message_id": null,
"sender_phone": "9190043XXXXX@c.us",
"sent_message_id": "f7b10126-5d5e-432f-941c-94ced28debac",
"delivery_info": {
"read": {
"919XXXXXXXXXXX@c.us": 1731984657443
},
"pending": [
"9184XXXXXXXXXX@c.us",
"919XXXXXXXXXXX@c.us"
],
"delivered": {
"919XXXXXXXXXXX@c.us": 1731214159000,
"919XXXXXXXXXXX@c.us": 1731195010000,
"919XXXXXXXXXXX@c.us": 1731175846000,
"919XXXXXXXXXXX@c.us": 1731175848000,
"919XXXXXXXXXXX@c.us": 1731175847000
},
"read_count": 0,
"delivered_count": 5
},
"flag_metadata": {
"status": false,
"response_id": "3A1AXXXXXXXXXX",
"response_type": "message",
"response_email": "91XXXXXXXXX@c.us",
"response_timestamp": "2024-11-26T15:16:32.179Z"
},
"poll_info": {
"options": {
"allowMultipleAnswers": true
},
"pollName": "pollQuestion",
"pollOptions": [
"option1",
"option2",
"option3"
]
},
"poll_results": {
"option1": {
"91903XXXXXX0@c.us": "2024-05-24T15:24:11.336Z"
},
"option2": {},
"option3": {}
},
"interactive": null,
"updated_at": "2024-05-13 11:19:36.114+00",
"message_ticket_id": null,
"unique_id": "3EB01F4653XX9XX05E9859"
}
```
Refer [Message](/api-reference/objects/the-message-object) object to find more details about `message object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('message.created', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# message.deleted
Source: https://docs.periskope.app/api-reference/webhooks/message.deleted
The `message.deleted` webhook is triggered when a message is deleted on whatsapp.
```json The Message Object theme={null}
{
"message_id": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us",
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"ack": "2",
"author": "9190043XXXXX@c.us",
"body": "Hello, world",
"broadcast": null,
"device_type": "android",
"flag_status": false,
"duration": null,
"forwarding_score": "0",
"from": "9190043XXXXX@c.us",
"from_me": true,
"has_media": true,
"has_quoted_msg": false,
"has_reaction": false,
"id": {
"id": "3EB01F4653XX9XX05E9859",
"fromMe": true,
"remote": "12036329726967XXXX@g.us",
"_serialized": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us"
},
"invite_v4": null,
"is_ephemeral": null, //disappearing messages
"is_forwarded": false,
"is_gif": false,
"is_starred": false,
"is_status": false,
"links": "[]",
"location": null,
"media_key": null,
"mentioned_ids": [],
"order_id": null,
"raw_data": null,
"to": "12036329726967XXXX@g.us",
"token": null,
"message_type": "image",
"vcards": [],
"chat_id": "12036329726967XXXX@g.us",
"timestamp": "2024-05-13 11:19:34+00",
"org_phone": "9190043XXXXX@c.us",
"broadcast_id": null,
"is_deleted": null,
"media": {
"path": "/storage/v1/object/public/message-media/2997xx64-89bf-48d3-9a22-b314fxx017e5/12036329726967XXXX@g.us/true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us/dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"size": 19940,
"filename": "dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"mimetype": "image/jpeg",
"dimensions": {
"ar": 1,
"width": 512,
"height": 512
}
},
"performed_by": "harsh.gour@hashlabs.dev",
"prev_body": null,
"quoted_message_id": null,
"sender_phone": "9190043XXXXX@c.us",
"sent_message_id": "f7b10126-5d5e-432f-941c-94ced28debac",
"delivery_info": {
"read": {
"919XXXXXXXXXXX@c.us": 1731984657443
},
"pending": [
"9184XXXXXXXXXX@c.us",
"919XXXXXXXXXXX@c.us"
],
"delivered": {
"919XXXXXXXXXXX@c.us": 1731214159000,
"919XXXXXXXXXXX@c.us": 1731195010000,
"919XXXXXXXXXXX@c.us": 1731175846000,
"919XXXXXXXXXXX@c.us": 1731175848000,
"919XXXXXXXXXXX@c.us": 1731175847000
},
"read_count": 0,
"delivered_count": 5
},
"flag_metadata": {
"status": false,
"response_id": "3A1AXXXXXXXXXX",
"response_type": "message",
"response_email": "91XXXXXXXXX@c.us",
"response_timestamp": "2024-11-26T15:16:32.179Z"
},
"poll_info": {
"options": {
"allowMultipleAnswers": true
},
"pollName": "pollQuestion",
"pollOptions": [
"option1",
"option2",
"option3"
]
},
"poll_results": {
"option1": {
"91903XXXXXX0@c.us": "2024-05-24T15:24:11.336Z"
},
"option2": {},
"option3": {}
},
"interactive": null,
"updated_at": "2024-05-13 11:19:36.114+00",
"message_ticket_id": null,
"unique_id": "3EB01F4653XX9XX05E9859"
}
```
Refer [Message](/api-reference/objects/the-message-object) object to find more details about `message object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('message.deleted', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# message.flagged
Source: https://docs.periskope.app/api-reference/webhooks/message.flagged
The `message.flagged` webhook is triggered when a message is flagged on Periskope.
```json The Message Object theme={null}
{
"message_id": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us",
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"ack": "2",
"author": "9190043XXXXX@c.us",
"body": "Hello, world",
"broadcast": null,
"device_type": "android",
"flag_status": false,
"duration": null,
"forwarding_score": "0",
"from": "9190043XXXXX@c.us",
"from_me": true,
"has_media": true,
"has_quoted_msg": false,
"has_reaction": false,
"id": {
"id": "3EB01F4653XX9XX05E9859",
"fromMe": true,
"remote": "12036329726967XXXX@g.us",
"_serialized": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us"
},
"invite_v4": null,
"is_ephemeral": null, //disappearing messages
"is_forwarded": false,
"is_gif": false,
"is_starred": false,
"is_status": false,
"links": "[]",
"location": null,
"media_key": null,
"mentioned_ids": [],
"order_id": null,
"raw_data": null,
"to": "12036329726967XXXX@g.us",
"token": null,
"message_type": "image",
"vcards": [],
"chat_id": "12036329726967XXXX@g.us",
"timestamp": "2024-05-13 11:19:34+00",
"org_phone": "9190043XXXXX@c.us",
"broadcast_id": null,
"is_deleted": null,
"media": {
"path": "/storage/v1/object/public/message-media/2997xx64-89bf-48d3-9a22-b314fxx017e5/12036329726967XXXX@g.us/true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us/dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"size": 19940,
"filename": "dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"mimetype": "image/jpeg",
"dimensions": {
"ar": 1,
"width": 512,
"height": 512
}
},
"performed_by": "harsh.gour@hashlabs.dev",
"prev_body": null,
"quoted_message_id": null,
"sender_phone": "9190043XXXXX@c.us",
"sent_message_id": "f7b10126-5d5e-432f-941c-94ced28debac",
"delivery_info": {
"read": {
"919XXXXXXXXXXX@c.us": 1731984657443
},
"pending": [
"9184XXXXXXXXXX@c.us",
"919XXXXXXXXXXX@c.us"
],
"delivered": {
"919XXXXXXXXXXX@c.us": 1731214159000,
"919XXXXXXXXXXX@c.us": 1731195010000,
"919XXXXXXXXXXX@c.us": 1731175846000,
"919XXXXXXXXXXX@c.us": 1731175848000,
"919XXXXXXXXXXX@c.us": 1731175847000
},
"read_count": 0,
"delivered_count": 5
},
"flag_metadata": {
"status": false,
"response_id": "3A1AXXXXXXXXXX",
"response_type": "message",
"response_email": "91XXXXXXXXX@c.us",
"response_timestamp": "2024-11-26T15:16:32.179Z"
},
"poll_info": {
"options": {
"allowMultipleAnswers": true
},
"pollName": "pollQuestion",
"pollOptions": [
"option1",
"option2",
"option3"
]
},
"poll_results": {
"option1": {
"91903XXXXXX0@c.us": "2024-05-24T15:24:11.336Z"
},
"option2": {},
"option3": {}
},
"interactive": null,
"updated_at": "2024-05-13 11:19:36.114+00",
"message_ticket_id": null,
"unique_id": "3EB01F4653XX9XX05E9859"
}
```
Refer [Message](/api-reference/objects/the-message-object) object to find more details about `message object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('message.flagged', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# message.ticket.attached
Source: https://docs.periskope.app/api-reference/webhooks/message.ticket.attached
The `message.ticket.attached` webhook is triggered when a message is attached to a ticket.
```json The Message Object theme={null}
{
"message_id": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us",
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"ack": "2",
"author": "9190043XXXXX@c.us",
"body": "Hello, world",
"broadcast": null,
"device_type": "android",
"flag_status": false,
"duration": null,
"forwarding_score": "0",
"from": "9190043XXXXX@c.us",
"from_me": true,
"has_media": true,
"has_quoted_msg": false,
"has_reaction": false,
"id": {
"id": "3EB01F4653XX9XX05E9859",
"fromMe": true,
"remote": "12036329726967XXXX@g.us",
"_serialized": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us"
},
"invite_v4": null,
"is_ephemeral": null, //disappearing messages
"is_forwarded": false,
"is_gif": false,
"is_starred": false,
"is_status": false,
"links": "[]",
"location": null,
"media_key": null,
"mentioned_ids": [],
"order_id": null,
"raw_data": null,
"to": "12036329726967XXXX@g.us",
"token": null,
"message_type": "image",
"vcards": [],
"chat_id": "12036329726967XXXX@g.us",
"timestamp": "2024-05-13 11:19:34+00",
"org_phone": "9190043XXXXX@c.us",
"broadcast_id": null,
"is_deleted": null,
"media": {
"path": "/storage/v1/object/public/message-media/2997xx64-89bf-48d3-9a22-b314fxx017e5/12036329726967XXXX@g.us/true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us/dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"size": 19940,
"filename": "dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"mimetype": "image/jpeg",
"dimensions": {
"ar": 1,
"width": 512,
"height": 512
}
},
"performed_by": "harsh.gour@hashlabs.dev",
"prev_body": null,
"quoted_message_id": null,
"sender_phone": "9190043XXXXX@c.us",
"sent_message_id": "f7b10126-5d5e-432f-941c-94ced28debac",
"delivery_info": {
"read": {
"919XXXXXXXXXXX@c.us": 1731984657443
},
"pending": [
"9184XXXXXXXXXX@c.us",
"919XXXXXXXXXXX@c.us"
],
"delivered": {
"919XXXXXXXXXXX@c.us": 1731214159000,
"919XXXXXXXXXXX@c.us": 1731195010000,
"919XXXXXXXXXXX@c.us": 1731175846000,
"919XXXXXXXXXXX@c.us": 1731175848000,
"919XXXXXXXXXXX@c.us": 1731175847000
},
"read_count": 0,
"delivered_count": 5
},
"flag_metadata": {
"status": false,
"response_id": "3A1AXXXXXXXXXX",
"response_type": "message",
"response_email": "91XXXXXXXXX@c.us",
"response_timestamp": "2024-11-26T15:16:32.179Z"
},
"poll_info": {
"options": {
"allowMultipleAnswers": true
},
"pollName": "pollQuestion",
"pollOptions": [
"option1",
"option2",
"option3"
]
},
"poll_results": {
"option1": {
"91903XXXXXX0@c.us": "2024-05-24T15:24:11.336Z"
},
"option2": {},
"option3": {}
},
"interactive": null,
"updated_at": "2024-05-13 11:19:36.114+00",
"message_ticket_id": null,
"unique_id": "3EB01F4653XX9XX05E9859"
}
```
Refer [Message](/api-reference/objects/the-message-object) object to find more details about `message object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('message.ticket.attached', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# message.unflagged
Source: https://docs.periskope.app/api-reference/webhooks/message.unflagged
The `message.unflagged` webhook is triggered when a message is unflagged on Periskope.
```json The Message Object theme={null}
{
"message_id": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us",
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"ack": "2",
"author": "9190043XXXXX@c.us",
"body": "Hello, world",
"broadcast": null,
"device_type": "android",
"flag_status": false,
"duration": null,
"forwarding_score": "0",
"from": "9190043XXXXX@c.us",
"from_me": true,
"has_media": true,
"has_quoted_msg": false,
"has_reaction": false,
"id": {
"id": "3EB01F4653XX9XX05E9859",
"fromMe": true,
"remote": "12036329726967XXXX@g.us",
"_serialized": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us"
},
"invite_v4": null,
"is_ephemeral": null, //disappearing messages
"is_forwarded": false,
"is_gif": false,
"is_starred": false,
"is_status": false,
"links": "[]",
"location": null,
"media_key": null,
"mentioned_ids": [],
"order_id": null,
"raw_data": null,
"to": "12036329726967XXXX@g.us",
"token": null,
"message_type": "image",
"vcards": [],
"chat_id": "12036329726967XXXX@g.us",
"timestamp": "2024-05-13 11:19:34+00",
"org_phone": "9190043XXXXX@c.us",
"broadcast_id": null,
"is_deleted": null,
"media": {
"path": "/storage/v1/object/public/message-media/2997xx64-89bf-48d3-9a22-b314fxx017e5/12036329726967XXXX@g.us/true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us/dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"size": 19940,
"filename": "dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"mimetype": "image/jpeg",
"dimensions": {
"ar": 1,
"width": 512,
"height": 512
}
},
"performed_by": "harsh.gour@hashlabs.dev",
"prev_body": null,
"quoted_message_id": null,
"sender_phone": "9190043XXXXX@c.us",
"sent_message_id": "f7b10126-5d5e-432f-941c-94ced28debac",
"delivery_info": {
"read": {
"919XXXXXXXXXXX@c.us": 1731984657443
},
"pending": [
"9184XXXXXXXXXX@c.us",
"919XXXXXXXXXXX@c.us"
],
"delivered": {
"919XXXXXXXXXXX@c.us": 1731214159000,
"919XXXXXXXXXXX@c.us": 1731195010000,
"919XXXXXXXXXXX@c.us": 1731175846000,
"919XXXXXXXXXXX@c.us": 1731175848000,
"919XXXXXXXXXXX@c.us": 1731175847000
},
"read_count": 0,
"delivered_count": 5
},
"flag_metadata": {
"status": false,
"response_id": "3A1AXXXXXXXXXX",
"response_type": "message",
"response_email": "91XXXXXXXXX@c.us",
"response_timestamp": "2024-11-26T15:16:32.179Z"
},
"poll_info": {
"options": {
"allowMultipleAnswers": true
},
"pollName": "pollQuestion",
"pollOptions": [
"option1",
"option2",
"option3"
]
},
"poll_results": {
"option1": {
"91903XXXXXX0@c.us": "2024-05-24T15:24:11.336Z"
},
"option2": {},
"option3": {}
},
"interactive": null,
"updated_at": "2024-05-13 11:19:36.114+00",
"message_ticket_id": null,
"unique_id": "3EB01F4653XX9XX05E9859"
}
```
Refer [Message](/api-reference/objects/the-message-object) object to find more details about `message object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('message.unflagged', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# message.updated
Source: https://docs.periskope.app/api-reference/webhooks/message.updated
The `message.updated` webhook is triggered when a message is edited on whatsapp.
```json The Message Object theme={null}
{
"message_id": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us",
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"ack": "2",
"author": "9190043XXXXX@c.us",
"body": "Hello, world",
"broadcast": null,
"device_type": "android",
"flag_status": false,
"duration": null,
"forwarding_score": "0",
"from": "9190043XXXXX@c.us",
"from_me": true,
"has_media": true,
"has_quoted_msg": false,
"has_reaction": false,
"id": {
"id": "3EB01F4653XX9XX05E9859",
"fromMe": true,
"remote": "12036329726967XXXX@g.us",
"_serialized": "true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us"
},
"invite_v4": null,
"is_ephemeral": null, //disappearing messages
"is_forwarded": false,
"is_gif": false,
"is_starred": false,
"is_status": false,
"links": "[]",
"location": null,
"media_key": null,
"mentioned_ids": [],
"order_id": null,
"raw_data": null,
"to": "12036329726967XXXX@g.us",
"token": null,
"message_type": "image",
"vcards": [],
"chat_id": "12036329726967XXXX@g.us",
"timestamp": "2024-05-13 11:19:34+00",
"org_phone": "9190043XXXXX@c.us",
"broadcast_id": null,
"is_deleted": null,
"media": {
"path": "/storage/v1/object/public/message-media/2997xx64-89bf-48d3-9a22-b314fxx017e5/12036329726967XXXX@g.us/true_12036329726967XXXX@g.us_3EB01F4653XX9XX05E9859_9190043XXXXX@c.us/dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"size": 19940,
"filename": "dbd33c9e-bedc-4df7-8a4c-f9eadf957ac9",
"mimetype": "image/jpeg",
"dimensions": {
"ar": 1,
"width": 512,
"height": 512
}
},
"performed_by": "harsh.gour@hashlabs.dev",
"prev_body": null,
"quoted_message_id": null,
"sender_phone": "9190043XXXXX@c.us",
"sent_message_id": "f7b10126-5d5e-432f-941c-94ced28debac",
"delivery_info": {
"read": {
"919XXXXXXXXXXX@c.us": 1731984657443
},
"pending": [
"9184XXXXXXXXXX@c.us",
"919XXXXXXXXXXX@c.us"
],
"delivered": {
"919XXXXXXXXXXX@c.us": 1731214159000,
"919XXXXXXXXXXX@c.us": 1731195010000,
"919XXXXXXXXXXX@c.us": 1731175846000,
"919XXXXXXXXXXX@c.us": 1731175848000,
"919XXXXXXXXXXX@c.us": 1731175847000
},
"read_count": 0,
"delivered_count": 5
},
"flag_metadata": {
"status": false,
"response_id": "3A1AXXXXXXXXXX",
"response_type": "message",
"response_email": "91XXXXXXXXX@c.us",
"response_timestamp": "2024-11-26T15:16:32.179Z"
},
"poll_info": {
"options": {
"allowMultipleAnswers": true
},
"pollName": "pollQuestion",
"pollOptions": [
"option1",
"option2",
"option3"
]
},
"poll_results": {
"option1": {
"91903XXXXXX0@c.us": "2024-05-24T15:24:11.336Z"
},
"option2": {},
"option3": {}
},
"interactive": null,
"updated_at": "2024-05-13 11:19:36.114+00",
"message_ticket_id": null,
"unique_id": "3EB01F4653XX9XX05E9859"
}
```
Refer [Message](/api-reference/objects/the-message-object) object to find more details about `message object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('message.updated', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# note.created
Source: https://docs.periskope.app/api-reference/webhooks/note.created
The `note.created` webhook is triggered when a private note is sent to a chat on Periskope.
```json The Private Note Object theme={null}
{
"message_id": "true_2634e275-ac58-4c85-892d-83882810fc1c_api",
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"ack": "3",
"body": "Hello World",
"from_me": true,
"message_type": "chat",
"chat_id": "91882424xxxx@c.us",
"timestamp": "2025-08-18T13:38:37.203+00:00",
"org_phone": "91882424xxxx@c.us",
"performed_by": "api",
"prev_body": null,
"quoted_message_id": "52643136-1573-4011-ad22-b95ca6ea8e0c",
"sender_phone": "91882424xxxx@c.us",
"sent_message_id": "2634e275-ac58-4c85-892d-83882810fc1c",
"updated_at": "2025-08-18T13:38:37.203+00:00",
"is_private_note": true,
"unique_id": "2634e275-ac58-4c85-892d-83882810fc1c",
"mentioned_ids": [],
"is_deleted": null
"media": {
"mimetype": "audio/wav",
"filename": "beep.wav",
"filedata": "data:audio/wav;base64,UklGRkKAAABXQVZFZm10IBAAAAABAAEAQB8A..."
}
}
```
Refer [Note](/api-reference/objects/the-note-object) object to find more details about `note object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('note.created', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# org.phone.connected
Source: https://docs.periskope.app/api-reference/webhooks/org.phone.connected
The `org.phone.connected` webhook is triggered when your org phone changes to a connected state from a disconnected state.
```json The Phone Object theme={null}
{
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"org_phone": "918527184400@c.us",
"created_at": "2024-12-15T11:47:26.668505+00:00",
"updated_at": "2025-01-20T07:51:48.209+00:00",
"wa_state": "CONNECTED",
"phone_id": "phone-bqzvyibhmwkaergr",
"qr_code": null,
"phone_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F918527184400%40c.us.jpg?timestamp=1737141384215",
"phone_name": "Support",
"first_connected_at": "2024-12-15T11:47:49.649+00:00",
"is_ready": true,
"label_ids": {
"label-bflirzqiodgianfh": true,
"label-rbdshklasmlbfczf": true
},
"labels": [
"test1",
"test2"
]
}
```
Refer [Phone](/api-reference/objects/the-phone-object) object to find more details about `phone object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('org.phone.connected', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# org.phone.disconnected
Source: https://docs.periskope.app/api-reference/webhooks/org.phone.disconnected
The `org.phone.disconnected` webhook is triggered when your org phone changes to a disconnected state.
```json The Phone Object theme={null}
{
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"org_phone": "918527184400@c.us",
"created_at": "2024-12-15T11:47:26.668505+00:00",
"updated_at": "2025-01-20T07:51:48.209+00:00",
"wa_state": "CONNECTED",
"phone_id": "phone-bqzvyibhmwkaergr",
"qr_code": null,
"phone_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F918527184400%40c.us.jpg?timestamp=1737141384215",
"phone_name": "Support",
"first_connected_at": "2024-12-15T11:47:49.649+00:00",
"is_ready": true,
"label_ids": {
"label-bflirzqiodgianfh": true,
"label-rbdshklasmlbfczf": true
},
"labels": [
"test1",
"test2"
]
}
```
Refer [Phone](/api-reference/objects/the-phone-object) object to find more details about `phone object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('org.phone.disconnected', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# org.phone.qr
Source: https://docs.periskope.app/api-reference/webhooks/org.phone.qr
The `org.phone.qr` webhook is triggered your when your org phone's QR code changes
```json The Phone Object theme={null}
{
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"org_phone": "918527184400@c.us",
"created_at": "2024-12-15T11:47:26.668505+00:00",
"updated_at": "2025-01-20T07:51:48.209+00:00",
"wa_state": "CONNECTED",
"phone_id": "phone-bqzvyibhmwkaergr",
"qr_code": null,
"phone_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F918527184400%40c.us.jpg?timestamp=1737141384215",
"phone_name": "Support",
"first_connected_at": "2024-12-15T11:47:49.649+00:00",
"is_ready": true,
"label_ids": {
"label-bflirzqiodgianfh": true,
"label-rbdshklasmlbfczf": true
},
"labels": [
"test1",
"test2"
]
}
```
Refer [Phone](/api-reference/objects/the-phone-object) object to find more details about `phone object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('org.phone.qr', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# org.phone.updated
Source: https://docs.periskope.app/api-reference/webhooks/org.phone.updated
The `org.phone.updated` webhook is triggered when your org phone number, name or image changes.
```json The Phone Object theme={null}
{
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"org_phone": "918527184400@c.us",
"created_at": "2024-12-15T11:47:26.668505+00:00",
"updated_at": "2025-01-20T07:51:48.209+00:00",
"wa_state": "CONNECTED",
"phone_id": "phone-bqzvyibhmwkaergr",
"qr_code": null,
"phone_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F918527184400%40c.us.jpg?timestamp=1737141384215",
"phone_name": "Support",
"first_connected_at": "2024-12-15T11:47:49.649+00:00",
"is_ready": true,
"label_ids": {
"label-bflirzqiodgianfh": true,
"label-rbdshklasmlbfczf": true
},
"labels": [
"test1",
"test2"
]
}
```
Refer [Phone](/api-reference/objects/the-phone-object) object to find more details about `phone object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('org.phone.updated', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# reaction.created
Source: https://docs.periskope.app/api-reference/webhooks/reaction.created
The `reaction.created` webhook is triggered when a reaction is created on Whatsapp.
```json The Reaction Object theme={null}
{
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"message_id": "false_120363297269676566@g.us_3EB01F4653BB9DD05E9859_919004389372@c.us",
"ack": "0",
"id": {
"id": "3EB01D1702AD13661CDAEA",
"fromMe": true,
"remote": "120363297269676566@g.us",
"_serialized": "true_120363297269676566@g.us_3EB01D1702AD13661CDAEA_919289665999@c.us"
},
"orphan": "0",
"reaction": "😀",
"read": true,
"reaction_id": "true_120363297269676566@g.us_3EB01D1702AD13661CDAEA_919289665999@c.us",
"timestamp": "2024-05-13 11:22:14+00",
"msg_id": {
"id": "3EB01F4653BB9DD05E9859",
"fromMe": false,
"remote": "120363297269676566@g.us",
"_serialized": "false_120363297269676566@g.us_3EB01F4653BB9DD05E9859_919004389372@c.us"
},
"orphan_reason": null,
"sender_id": "919289665999@c.us",
"org_phone": "919289665999@c.us",
"chat_id": "120363297269676566@g.us",
"unique_id": "3EB01F4653BB9DD05E9859"
}
```
Refer [Reaction](/api-reference/objects/the-reaction-object) object to find more details about `reaction object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('reaction.created', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# reaction.updated
Source: https://docs.periskope.app/api-reference/webhooks/reaction.updated
The `reaction.updated` webhook is triggered when a reaction is updated on Periskope.
```json The Reaction Object theme={null}
{
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"message_id": "false_120363297269676566@g.us_3EB01F4653BB9DD05E9859_919004389372@c.us",
"ack": "0",
"id": {
"id": "3EB01D1702AD13661CDAEA",
"fromMe": true,
"remote": "120363297269676566@g.us",
"_serialized": "true_120363297269676566@g.us_3EB01D1702AD13661CDAEA_919289665999@c.us"
},
"orphan": "0",
"reaction": "😀",
"read": true,
"reaction_id": "true_120363297269676566@g.us_3EB01D1702AD13661CDAEA_919289665999@c.us",
"timestamp": "2024-05-13 11:22:14+00",
"msg_id": {
"id": "3EB01F4653BB9DD05E9859",
"fromMe": false,
"remote": "120363297269676566@g.us",
"_serialized": "false_120363297269676566@g.us_3EB01F4653BB9DD05E9859_919004389372@c.us"
},
"orphan_reason": null,
"sender_id": "919289665999@c.us",
"org_phone": "919289665999@c.us",
"chat_id": "120363297269676566@g.us",
"unique_id": "3EB01F4653BB9DD05E9859"
}
```
Refer [Reaction](/api-reference/objects/the-reaction-object) object to find more details about `reaction object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('reaction.updated', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# ticket.created
Source: https://docs.periskope.app/api-reference/webhooks/ticket.created
The `ticket.created` webhook is triggered when a new ticket is created on Periskope.
```json The Ticket Object theme={null}
{
"chat": {
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"org_phone": "91900438XXXX@c.us",
"chat_id": "919X836X025X090@Xc.us",
"members": {
"918527184400@c.us": {
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"chat_id": "919537851844@c.us",
"is_admin": true,
"org_phone": "918527184400@c.us",
"contact_id": "918527184400@c.us",
"is_internal": true,
"contact_name": "Support",
"contact_color": "#B4876E",
"contact_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F918527184400%40c.us.jpg?timestamp=1737690126280",
"is_super_admin": true
},
"919537851844@c.us": {
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"chat_id": "919537851844@c.us",
"is_admin": true,
"org_phone": "918527184400@c.us",
"contact_id": "919537851844@c.us",
"is_internal": false,
"contact_name": "BK Local1",
"contact_color": "#B4876E",
"contact_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F919537851844%40c.us.jpg?timestamp=1737689973340",
"is_super_admin": true
}
},
"is_muted": false,
"chat_name": "Demo Chat",
"chat_type": "chat",
"chat_image": "/storage/image.jpeg",
"created_at": "2025-01-26T02:30:50+00:00",
"chat_labels": "label1, label2",
"invite_link": "https://chat.whatsapp.com/invite/BZcwk7oCxxVIhExxxcmKxN"
"custom_properties": {
"Property1": "opXtion1",
"Property2": "opXtion1",
"Property3": "opXtion1"
},
"group_description": null
},
"message": {
"body": "hello",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
},
"ticket": {
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"status": "open",
"subject": "Sample Ticket Subject",
"assignee": "assignee@example.com",
"due_date": "2024-06-15T12:00:00+00:00",
"priority": 2,
"closed_at": "2024-06-14T12:00:00+00:00",
"closed_by": "closedby@example.com",
"raised_by": "raisedby@example.com",
"ticket_id": "TICKET-12345",
"created_at": "2024-05-24T08:30:00+00:00",
"is_deleted": false,
"assigned_by": "manager@example.com",
"ticket_labels": "label1, label2",
"quoted_message_id": "3EB0DAB631F7E580EAAE0C"
"ticket_custom_properties": {
"property-1": "value-1",
"property-2": "value-2",
"property-3": "value-3"
},
"first_assigned_at" : null
},
"attached_messages": [{
"body": "hello",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
},{
"body": "attached message 1",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
}]
}
```
This will contain only ticket data and no details regarding the message or chat it has
been raised for. To get more details about the chat and message, you can use [Get ticket info API](/api-reference/tickets/get-ticket-by-id).
Refer [Ticket Info Object](/api-reference/objects/the-ticket-info-object) to find more details about chat and message details related to the ticket.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('ticket.created', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# ticket.deleted
Source: https://docs.periskope.app/api-reference/webhooks/ticket.deleted
The `ticket.deleted` webhook is triggered when a ticket is deleted on Periskope.
```json The Ticket Object theme={null}
{
"chat": {
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"org_phone": "91900438XXXX@c.us",
"chat_id": "919X836X025X090@Xc.us",
"members": {
"918527184400@c.us": {
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"chat_id": "919537851844@c.us",
"is_admin": true,
"org_phone": "918527184400@c.us",
"contact_id": "918527184400@c.us",
"is_internal": true,
"contact_name": "Support",
"contact_color": "#B4876E",
"contact_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F918527184400%40c.us.jpg?timestamp=1737690126280",
"is_super_admin": true
},
"919537851844@c.us": {
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"chat_id": "919537851844@c.us",
"is_admin": true,
"org_phone": "918527184400@c.us",
"contact_id": "919537851844@c.us",
"is_internal": false,
"contact_name": "BK Local1",
"contact_color": "#B4876E",
"contact_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F919537851844%40c.us.jpg?timestamp=1737689973340",
"is_super_admin": true
}
},
"is_muted": false,
"chat_name": "Demo Chat",
"chat_type": "chat",
"chat_image": "/storage/image.jpeg",
"created_at": "2025-01-26T02:30:50+00:00",
"chat_labels": "label1, label2",
"invite_link": "https://chat.whatsapp.com/invite/BZcwk7oCxxVIhExxxcmKxN"
"custom_properties": {
"Property1": "opXtion1",
"Property2": "opXtion1",
"Property3": "opXtion1"
},
"group_description": null
},
"message": {
"body": "hello",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
},
"ticket": {
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"status": "open",
"subject": "Sample Ticket Subject",
"assignee": "assignee@example.com",
"due_date": "2024-06-15T12:00:00+00:00",
"priority": 2,
"closed_at": "2024-06-14T12:00:00+00:00",
"closed_by": "closedby@example.com",
"raised_by": "raisedby@example.com",
"ticket_id": "TICKET-12345",
"created_at": "2024-05-24T08:30:00+00:00",
"is_deleted": false,
"assigned_by": "manager@example.com",
"ticket_labels": "label1, label2",
"quoted_message_id": "3EB0DAB631F7E580EAAE0C"
"ticket_custom_properties": {
"property-1": "value-1",
"property-2": "value-2",
"property-3": "value-3"
},
"first_assigned_at" : null
},
"attached_messages": [{
"body": "hello",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
},{
"body": "attached message 1",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
}]
}
```
Refer [Ticket](/api-reference/objects/the-ticket-info-object) object to find more details about `ticket info object`.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('ticket.deleted', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# ticket.updated
Source: https://docs.periskope.app/api-reference/webhooks/ticket.updated
The `ticket.updated` webhook is triggered when ticket details are updated on Periskope.
```json The Ticket Object theme={null}
{
"chat": {
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"org_phone": "91900438XXXX@c.us",
"chat_id": "919X836X025X090@Xc.us",
"members": {
"918527184400@c.us": {
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"chat_id": "919537851844@c.us",
"is_admin": true,
"org_phone": "918527184400@c.us",
"contact_id": "918527184400@c.us",
"is_internal": true,
"contact_name": "Support",
"contact_color": "#B4876E",
"contact_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F918527184400%40c.us.jpg?timestamp=1737690126280",
"is_super_admin": true
},
"919537851844@c.us": {
"org_id": "2997dd64-89bf-48d3-9a22-b314fca017e5",
"chat_id": "919537851844@c.us",
"is_admin": true,
"org_phone": "918527184400@c.us",
"contact_id": "919537851844@c.us",
"is_internal": false,
"contact_name": "BK Local1",
"contact_color": "#B4876E",
"contact_image": "https://storage.googleapis.com/periskope-images/2997dd64-89bf-48d3-9a22-b314fca017e5%2F919537851844%40c.us.jpg?timestamp=1737689973340",
"is_super_admin": true
}
},
"is_muted": false,
"chat_name": "Demo Chat",
"chat_type": "chat",
"chat_image": "/storage/image.jpeg",
"created_at": "2025-01-26T02:30:50+00:00",
"chat_labels": "label1, label2",
"invite_link": "https://chat.whatsapp.com/invite/BZcwk7oCxxVIhExxxcmKxN"
"custom_properties": {
"Property1": "opXtion1",
"Property2": "opXtion1",
"Property3": "opXtion1"
},
"group_description": null
},
"message": {
"body": "hello",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
},
"ticket": {
"org_id": "2997xx64-89bf-48d3-9a22-b314fxx017e5",
"status": "open",
"subject": "Sample Ticket Subject",
"assignee": "assignee@example.com",
"due_date": "2024-06-15T12:00:00+00:00",
"priority": 2,
"closed_at": "2024-06-14T12:00:00+00:00",
"closed_by": "closedby@example.com",
"raised_by": "raisedby@example.com",
"ticket_id": "TICKET-12345",
"created_at": "2024-05-24T08:30:00+00:00",
"is_deleted": false,
"assigned_by": "manager@example.com",
"ticket_labels": "label1, label2",
"quoted_message_id": "3EB0DAB631F7E580EAAE0C"
"ticket_custom_properties": {
"property-1": "value-1",
"property-2": "value-2",
"property-3": "value-3"
},
"first_assigned_at" : null
},
"attached_messages": [{
"body": "hello",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
},{
"body": "attached message 1",
"chat_id": "X919836025090@c.us",
"org_phone": "X91900438XXXX@c.us",
"timestamp": "2024-05-13T17:27:15+00:00",
"media_path": "/path/to/media",
"message_id": "true_91983602XXXX@c.us_3EB0DAB631F7E58XXXXE0C",
"sender_name": "Periskope Central",
"performed_by": "demo@email.com",
"sender_phone": "91900438XXXX"
}]
}
```
This will contain only ticket data and no details regarding the message or chat it has
been raised for. To get more details about the chat and message, you can use [Get ticket info API](/api-reference/tickets/get-ticket-by-id).
Refer [Ticket Info Object](/api-reference/objects/the-ticket-info-object) to find more details about chat and message details related to the ticket.
```ts Node.js theme={null}
import { PeriskopeApi } from '@periskope/periskope-client';
const client = new PeriskopeApi({
authToken: 'YOUR_API_KEY',
phone: 'YOUR_PHONE_NUMBER', // e.g., '919876543210'
});
client.on('ticket.updated', (data) => {
console.log(data);
});
```
### Event structure 📦
You'll be receiving the data in the following format:
```json theme={null}
{
"event_type": "",
"data": "", // complete data object as mentioned in Objects section
"org_id": "",
"timestamp": "" // timestamp of the event creation
}
```
# Update Webhook
Source: https://docs.periskope.app/api-reference/webhooks/update-webhook
api-reference/openapi-generated.json PATCH /v1/webhooks/{id}
Updates a webhook subscription row — at least one of hookUrl, integrationName, integrationMetadata, integrationType, isSubscribed or name.
# Automated Assignment
Source: https://docs.periskope.app/automated-assignment
Automatically route conversations and tickets to the right team members. Balance workload fairly. Eliminate manual routing. Keep assignments consistent and fast.
## Overview
Not every conversation needs manual routing, but every conversation needs to reach the right person. With Periskope's Automated Assignments Templates, you can automate how chats and tickets are distributed to your team. Round robin ensures fair workload balance. Creator assignment maintains continuity. Let automation handle routing so your team can focus on handling conversations.
## How It Works
Automated Assignments Templates are pre-built rules that assign chats or tickets automatically based on triggers and logic. Instead of building automation from scratch, you activate a template and optionally add conditions.
* Select a template from the Automated Assignments category
* Review the pre-configured trigger and assignment logic
* Optionally add conditions to refine when assignments happen
* Select which team members to include in the assignment pool
* Save and activate the rule
* Chats and tickets are now assigned automatically
The entire process takes minutes. Assignments are instant, fair, and eliminate manual routing work.
## Getting Started with Automated Assignments
> **Step 1: Access Automation Rules and Start from Template**
From your Periskope dashboard > go to Automation Rules > Click New Rule > Click Start from Template. You’ll see templates organized by category. Look for the Automated Assignments category.
> **Step 2: Choose a Template**
Inside Automated Assignments, select the template that matches your workflow. See available templates below.
> **Step 3: Review and Optionally Customize**
Each template comes with a trigger and action already configured. Review these to understand how the template will work. You can see what conditions will activate the assignment and what logic will be used.
> **Step 4: Select Your Team Members**
Choose which agents should be included in the assignment pool. For round robin, all selected members participate equally.
> **Step 5: Save and Activate**
Click Save to store your rule. Click Activate to turn it live. Assignments now happen automatically.
## Available Automated Assignments Templates
1. **Assign New Chat in a Round Robin Fashion**
**When to use:** You want to distribute incoming chats evenly across your team. This helps balance workload automatically, so no single agent gets overwhelmed while others are underutilized.
**Use case:** Your support team gets a steady stream of new customer chats. Instead of assigning manually, automation cycles through your team ensuring everyone gets an equal share of new conversations. Chat 1 goes to Alice, Chat 2 to Bob, Chat 3 to Carol, then back to Alice.
2. **Assign Chat to the Creator of Chat**
**When to use:** Conversations need ownership from the person who initiated or is already contextually involved. This works well when you want to maintain continuity and avoid unnecessary back-and-forth within the team.
**Use case:** Sarah starts a conversation with a customer. The system automatically assigns the chat to Sarah, so she owns it from the beginning. No need to route it separately. Context is maintained from the first interaction.
3. **Assign New Ticket in a Round Robin Fashion**
**When to use:** Support teams handling a steady flow of tickets need fair distribution and faster response times without manual intervention. Ensures consistent load balancing across the team.
**Use case:** Your support team receives 50 new tickets daily. Instead of assigning manually, round robin automatically distributes them. Each agent gets 10-12 tickets fairly, keeping workload balanced and preventing any agent from being overloaded.
4. **Assign Ticket to the Chat Assignee**
**When to use:** Tickets are closely tied to ongoing conversations. This is useful when you want the same person handling the chat to also manage the ticket, keeping context intact and reducing handoffs.
**Use case:** A customer's ongoing chat with Bob becomes a support ticket. Instead of routing it elsewhere, the ticket automatically goes to Bob who already understands the full context of the conversation. No handoff needed.
# Automated Escalation
Source: https://docs.periskope.app/automated-escalation
Surface critical issues instantly. Alert the right people at the right time. Prevent delays on important conversations. Keep SLA breaches and priority messages from falling through the cracks.
## Overview
As conversations scale, it's easy for important messages to get delayed or missed, especially when they need immediate attention. With Periskope's Automated Escalations Templates, you can automate how critical issues are surfaced and acted on. SLA breaches trigger instant notifications. Key customers get priority handling. Escalations happen automatically so nothing important gets missed.
## How It Works
Automated Escalations Templates are pre-built rules that surface critical issues by notifying the right people. Instead of building automation from scratch, you activate a template and customize who gets notified.
1. Select a template from the Automated Escalations category
2. Review the pre-configured trigger and escalation action
3. Optionally refine conditions to narrow what gets escalated
4. Select who should receive escalation notifications
5. Save and activate the rule
6. Critical issues are now escalated automatically
The entire process takes minutes. Escalations are instant, targeted, and ensure nothing critical gets missed.
## Getting Started with Automated Escalations
> **Step 1: Access Automation Rules and Start from Template**
From your Periskope dashboard > go to Automation Rules > Click New Rule > Click Start from Template. You’ll see templates organized by category. Look for the Automated Escalations category.
> **Step 2: Choose a Template**
Inside Automated Escalations, select the template that matches your needs. See available templates below.
> **Step 3: Review and Optionally Customize**
Each template comes with a trigger and action already configured. Review these to understand how the escalation will work and what conditions will activate it.
> **Step 4: Select Escalation Recipients**
Choose who should receive escalation notifications. These could be team leads, managers, or specific departments. Multiple recipients can be notified.
> **Step 5: Save and Activate**
Click Save to store your rule. Click Activate to turn it live. Critical issues are now escalated automatically.
## Available Automated Escalations Templates
1. **Trigger an Email for SLA Breach**
**When to use:** Response times are critical and delays need immediate attention. This ensures that whenever an SLA is at risk or breached, the right stakeholders are notified instantly, helping teams take action before it impacts customer experience.
**Use case:** A customer message hasn't received a response in 4 hours (your SLA is 2 hours). The system automatically sends an email to your support manager saying: 'SLA Breach Alert: Message from VIP Customer XYZ has been pending for 4 hours. Immediate attention required.' Manager can take action instantly.
2. **Forward Message from Specific Senders**
**When to use:** Certain contacts or accounts need higher visibility. This ensures that messages from key customers or priority senders are automatically forwarded to the right people, so nothing important goes unnoticed.
**Use case:** Your biggest client sends a message. Instead of it sitting in the regular queue, the system automatically forwards it to your account manager with a note: 'Priority: Message from key account XYZ.' The account manager sees it immediately and can prioritize accordingly.
# Automated Flagging
Source: https://docs.periskope.app/automated-flagging
Surface messages that need attention instantly. Highlight priority conversations. Never miss important updates. Keep your team focused on what matters.
## Overview
As conversations grow, it becomes harder to keep track of which messages actually need attention. With Periskope's Automated Flagging Templates, you can automatically highlight important messages. Keywords trigger flags. Mentions get marked. Urgent issues surface without manual scanning. Your team focuses on what matters most.
## How It Works
Automated Flagging Templates are pre-built rules that automatically flag messages based on triggers and conditions. Instead of building automation from scratch, you activate a template and customize what gets flagged.
* Select a template from the Automated Flagging category
* Review the pre-configured trigger and flag action
* Optionally customize keywords or conditions
* Configure who sees these flagged messages
* Save and activate the rule
* Important messages are now flagged automatically
The entire process takes minutes. Flagging is instant, visible, and ensures nothing gets overlooked.
## Getting Started with Automated Flagging
> **Step 1: Access Automation Rules and Start from Template**
From your Periskope dashboard > go to Automation Rules > Click New Rule > Click Start from Template. You’ll see templates organized by category. Look for the Automated Flagging category.
> **Step 2: Choose a Template**
Inside Automated Flagging, select the template that matches your needs. See available templates below.
> **Step 3: Review and Optionally Customize**
Each template comes with a trigger and action already configured. Review these to understand how the escalation will work and what conditions will activate it.
> **Step 4: Customize Conditions**
Edit keywords or other conditions to match what matters to your team. Add, remove, or modify keywords or conditions to better capture what needs flagging.
> **Step 5: Save and Activate**
Click Save to store your rule. Click Activate to turn it live. Messages are now flagged automatically.
## Available Automated Flagging Templates
1. **Flag Messages for Specific Keywords**
**When to use:** Certain words or phrases indicate priority or urgency. This helps your team quickly identify messages that need immediate attention, without having to manually scan every conversation.
**Use case:** A customer message arrives saying 'This is urgent - our system is down!' The keyword 'urgent' triggers an automatic flag. The message appears highlighted in your inbox, so it gets attention first. Your team sees it immediately instead of it sitting in a queue.
2. **Flag Messages on Mentions**
**When to use:** Multiple people are involved in conversations. This ensures that whenever someone is tagged, the message is automatically flagged, making it easier to track and respond without delays.
**Use case:** Someone mentions @David in a group chat asking 'David, can you approve this?' The message is automatically flagged for David. He sees it immediately in his flagged messages and knows it needs his attention, reducing chances of the request being missed.
# Automated Notifications
Source: https://docs.periskope.app/automated-notifications
Surface messages that need attention instantly. Push real-time updates to external systems. Keep your team aligned and respond quickly.
## Overview
As conversations scale, it’s not always possible to stay on top of every message in real time. With Periskope’s Automated Notifications, you can set up automated notifications, so the right updates reach the right place instantly. Triggers and actions are pre-configured. Your team stays in sync without manual monitoring.
## How It Works
Automated Notification Templates are pre-built rules that automatically push message data to other platforms based on triggers. Instead of building automation from scratch, you activate a template and refine how and when the notification triggers.
* Select a template from the Automated Notifications category
* Review the pre-configured trigger and notification action
* Optionally add conditions to refine the workflow
* Configure the external endpoint or Slack channel
* Save and activate the rule
* Important updates are now delivered automatically
The entire process takes minutes. Notifications are instant, ensuring nothing gets overlooked.
## Getting Started with Automated Notifications
> **Step 1: Access Automation Rules and Start from Template**
From your Periskope dashboard > go to Automation Rules > Click New Rule > Click Start from Template. You’ll see templates organized by category. Look for the Automated Notifications category.
> **Step 2: Choose a Template**
Inside Automated Notifications, select the template that matches your needs. See available templates below.
> **Step 3: Review and Optionally Customize**
Each template comes with a trigger and action already configured. Review these to understand how the escalation will work and what conditions will activate it.
> **Step 4: Save and Activate**
Click Save to store your rule. Click Activate to turn it live. Notifications are now sent automatically.
## Available Automated Notification Templates
1. **Send Webhook Notification on Every Message**
**When to use:** Use this when you need to bridge the gap between Periskope and your own internal database or proprietary software. It is ideal for teams that require high-level customization for data storage or complex backend triggers that aren’t handled natively.
**Use case:** A new message arrives from a customer, and the webhook instantly pushes that data to your CRM to update a lead's activity log or triggers an automated billing process in your finance tool.
2. **Send Slack Notification on Every New Message**
**When to use:** This is best for teams that live in Slack and want to reduce the "toggle tax" of switching between platforms. It ensures that high-velocity conversations are visible to everyone in a shared channel without requiring manual scanning of the dashboard.
**Use case:** When a message is received in a high-priority group chat, it is instantly mirrored to a specific Slack channel so your support or sales team can coordinate a response in real-time without leaving their primary communication hub.
# Automated Replies
Source: https://docs.periskope.app/automated-replies
Send instant, consistent responses to customer messages automatically. Handle repetitive queries without manual effort. Keep conversations responsive 24/7.
## Overview
Not every message needs manual effort, but every message still needs a response. With Periskope's Automated Replies Templates, you can automate responses so your team can focus on more important conversations. Greetings, common questions, after-hours messages, mentions; let automation handle the repetitive replies while your team focuses on complex issues.
## How It Works
Automated Replies Templates are pre-built rules that send messages automatically based on triggers and conditions. Instead of building automation from scratch, you activate a template and customize the reply message.
* Select a template from the Automated Replies category
* Review the pre-configured trigger and reply message
* Customize the reply text to match your tone
* Optionally refine conditions (keywords, hours, etc.)
* Save and activate the rule
* Automatic replies are now sent on matching messages
The entire process takes minutes. Replies are instant, consistent, and can be customized for any scenario.
## Getting Started with Automated Replies
> **Step 1: Access Automation Rules**
From your Periskope dashboard, go to Automation Rules > Click New Rule > Click Start from Template. You'll see templates organized by category. Look for the Automated Replies category.
> **Step 2: Choose a Template**
Inside Automated Ticketing, you’ll find several ready-to-use templates. Pick the one that matches your workflow. See templates below.
> **Step 3: Review and Optionally Customize**
The template comes with trigger and action pre-configured. You can use it as-is or add conditions for more control. The conditions are also pre-configured. Adjust them if needed to match your exact workflow if required.
> **Step 4: Save and Activate**
Click Save to store your rule. Click Activate to turn it live. Replies are now sent automatically.
## Available Automated Replies Templates
1. **Automated Replies on Message with Keywords**
**When to use:** You handle high volumes of repetitive queries like greetings, common questions, or initial touchpoints. This ensures every message gets an immediate, consistent response and reduces wait times while taking repetitive load off your team.
**Use case:** A customer sends 'Hi! Do you have any job openings?' Your autoreply responds instantly: 'Thanks for reaching out! We received your message and will review your inquiry within 24 hours.' Your team then follows up with a substantive response.
2. **Automated Replies for Messages Outside Business Hours**
**When to use:** Your team isn't available 24/7 but you still want to acknowledge incoming messages. This is important for maintaining responsiveness, setting clear expectations on response times, and keeping a reliable customer experience even when no one is online.
**Use case:** A customer sends a message at 11 PM. Instead of silence, they automatically receive: 'Thanks for your message! We're currently closed but will respond first thing in the morning. We appreciate your patience.' This maintains trust and sets realistic expectations.
3. **Automated Replies for Mentions**
**When to use:** Multiple team members are involved in conversations. This works well in collaborative environments where it helps ensure that tagged messages are acknowledged quickly, reducing chances of delays and keeping internal coordination smooth and responsive.
**Use case:** Someone mentions @Sarah in a group chat asking for budget approval. Sarah automatically receives: 'Thanks for looping me in! I've received your message and will review it shortly.' Sarah gets notified immediately and knows the mention was received, eliminating follow-up pings.
# Automated Ticketing
Source: https://docs.periskope.app/automated-ticketing-rules
Automatically create tickets from customer queries using pre-built templates. Set up automation in minutes, not hours. Never manually create another ticket again.
## Overview
Manually creating tickets for every customer query can get repetitive, and it's easy to miss things when conversations scale. With Periskope's Automated Ticketing Templates, you can automate this entire process in just a few steps. Pick a template, optionally add conditions, save, and you're done. Tickets are created automatically based on your rules.
## How It Works
Automated Ticketing Templates are pre-built rules that come with triggers and actions already configured. Instead of building automation from scratch, you activate a template and optionally customize it.
* Select a template from the Automated Ticketing category
* Review the pre-configured trigger and action
* Optionally add conditions to refine when it triggers
* Save and publish the rule
* Tickets are now created automatically
The entire process takes minutes. No coding. No complex setup. Just activate and go.
## Getting Started with Templates
> **Step 1: Access Automation Rules**
From your Periskope dashboard > go to Automation Rules > Click New Rule > Click Start from Template. You'll see templates organized by category. Look for the Automated Ticketing category.
> **Step 2: Choose a Template**
Inside Automated Ticketing, you'll find several ready-to-use templates. Pick the one that matches your workflow. See templates below.
> **Step 3: Review and Optionally Customize**
The template comes with trigger and action pre-configured. You can use it as-is or add conditions for more control.
> **Step 4: Save and Publish**
Click Save to store your rule. Click Publish to activate it. Your automation is now live.
## Available Automated Ticketing Templates
1. **Create a ticket for new customer query**
**When to use:** Your team flags customer queries during conversations that need tracking. Automatically converts those flags into tickets so nothing is missed.
**Use case:** Support team reads a WhatsApp message, sees it needs a ticket, flags it. Automation instantly creates the ticket. No manual work.
2. **Create a ticket when response SLA is breached**
**When to use:** You want tickets automatically created when your team takes too long to respond. Helps escalate slow conversations.
**Use case:** Customer message arrives. Team doesn't respond in your SLA window (e.g., 2 hours). Ticket is automatically created for escalation.
3. **Create a ticket for specific keywords**
**When to use:** Certain keywords indicate high-priority issues that should always get tickets. Let automation catch them.
**Use case:** Customer says, 'My account is broken.' The keyword 'broken' triggers ticket creation automatically. No manual flagging needed.
4. **Create or append ticket on every new message**
**When to use:** You want every message to become a ticket automatically. Best for high-volume support where everything needs tracking.
**Use case:** B2B support where every customer message must have a trackable ticket. Automation handles it all.
5. **Create a ticket for mentions**
**When to use:** Mentions in group chats often indicate someone needs to take action. Automatically create tickets to ensure follow-up.
**Use case:** Someone mentions @Sarah in a chat asking for help. A ticket is automatically assigned to Sarah. She gets notified immediately.
# Export and Analyze Your Data
Source: https://docs.periskope.app/export-and-analyze-your-data
Access complete WhatsApp conversation data, tickets, messages, and call logs. Export in minutes with filters and formatting options. No scrambling for data when you need it.
## Overview
Ever needed a specific piece of data from your WhatsApp conversations and realized it's not exactly easy to pull together when you actually need it? With Periskope's Data Exports feature, you can access and export all that data in just a few clicks. Export chats, tickets, messages, phone numbers, chat actions, and call logs, all with detailed metadata to help you actually make sense of it later.
## How It Works
Data Exports is accessible from the Analytics Dashboard. Go to Analytics > Data Exports. You'll see different export options for different data types:
* Chat Exports - Complete conversation history
* Ticket Exports - Support ticket information
* Message Exports - Detailed communication data
* Phones Export - Phone number data
* Chat Actions Export - Changes and audit trails
* Call Logs Export - Audio and video call history
Each export type has its own filters and options. Pick what you need, configure it, and download or email the data.
## Chat Exports
Export complete chat history including timestamps and metadata. Use this for reviewing conversations, analyzing customer interactions, or archiving data.
* **Date Range:** Choose how far back to go. Options: Last 24 hours, Last 7 days, Last 30 days, Custom date range, or Full history. Smaller date ranges export faster.
* **Chat Type:** Filter by chat type, All chats, Group chats only, One-on-one chats only. This helps you focus on what you need.
* **Export Format:** Choose between Simplified format (easier to read, clean layout) or Legacy format (original system format). Most users prefer simplified.
* **Export Type:** Download directly or receive via email. Email is useful for large exports that take time to generate.
## Ticket Exports
Export ticket information to track support performance. Useful for reporting, audits, or external analysis.
* **Filter by Status:** Export all tickets or filter by status: Open, In Progress, Closed. This helps you analyze resolution rates or see what's pending.
* **Filter by Priority:** Focus on specific priority levels: Urgent, High, Normal, Low. See how your team handles different severity levels.
## Message Exports
Get granular control over message data. Export includes message body, timestamps, sender, and metadata.
* **Full Message Data:** Export all messages with complete details. Useful for analyzing communication patterns, sentiment, or customer interactions.
* **Flagged Messages Filter:** Export only flagged messages. This is useful for reviewing important conversations, escalations, or messages that need follow-up.
* **Deleted Messages Filter:** Include deleted messages in your export. This is particularly useful for compliance, audits, or investigating sensitive situations.
## Phones Export
Export phone number data and associated metadata. Includes both active and previously disconnected numbers.
* **What's Included:** Phone numbers, connection status (active/disconnected), metadata, date connected, date disconnected. Useful for understanding your contact base and managing numbers.
* **Use Cases:** Track which numbers are active, identify dormant numbers to clean up, manage phone inventory, or perform audits of your connected numbers.
## Chat Actions Export
Track changes within chats over time. Export history of actions taken in conversations for audit trails and team management insights.
* **Member Additions:** Track when team members were added to chats. See who joined conversations and when.
* **Member Removals:** See when team members left or were removed from chats. Useful for understanding collaboration patterns.
* \*\*Role Changes: \*\*Track promotions, demotions, and role reassignments within chat groups. Understand how team structure evolves.
## Call Logs Export
Access your organization's call history. Export audio and video calls with relevant details and dates. Useful for:
* **Audio Calls:** Track all audio calls made and received. Includes caller, recipient, duration, timestamp, and call status.
* **Video Calls:** See all video calls with full details. Useful for understanding video communication usage and patterns.
* **Call Tracking Use Cases:** Monitor communication channels, analyze call patterns, track usage, or ensure compliance with communication policies.
# AI Credits
Source: https://docs.periskope.app/features/ai-credits
Understand how AI credits work, how many you get each month, and how to top up when you need more.
## Overview
AI credits are consumed whenever Periskope runs an AI model on your behalf. They are separate from broadcast credits, which only cover bulk message sends.
The following features draw from your AI credit balance:
* **AI Agent** — automated replies, tool calls and agent runs
* **AI Assistant** — the in-chat assistant that drafts and summarizes
* **Workspace Assistant** — questions you ask about your workspace data
* **AI functions** — AI-powered actions used inside automation rules
* **Agent training** — self-training runs over your past conversations
## Monthly Credits
* You receive **5,000 AI credits per user + additional phone** in your workspace every month
* You do not receive credits for the first free phone in your workspace
* Credits reset on your monthly billing date
* On a yearly plan, the full year's allowance is granted upfront at the start of the billing cycle
**Example:** If you have 5 users, you receive 25,000 AI credits per month.
You can track your balance and consumption at any time under `AI > Credit Usage`.
The page shows your **credits available** (split into top-up and recurring), your **next renewal** date, what you've used **this cycle**, and a **Transactions** table you can filter by last 24 hours, 7 days, 30 days, or all time. **Export** downloads the transactions, and **Buy credits** takes you straight to a topup.
Recurring AI credits are included on the **Pro** plan. Starter plans do not receive a monthly AI allowance and can use AI features through topup credits.
New workspaces start with **1,000 free AI credits** during the free trial so you can try AI features before subscribing.
## How Usage Is Measured
Credits are charged on the amount of text the model reads and writes for each request, so a short reply costs a fraction of a credit while a long conversation with lots of context costs more.
A few things that affect how quickly credits are used:
* Longer chat histories and larger knowledge bases mean more context per request
* Longer AI responses cost more than short ones
* Repeated context within a conversation is charged at a heavily reduced rate
## Topup Credits
If you run out of monthly credits, you can purchase additional topup credits.
* Navigate to `Settings > Manage Plans > Topup Credits`
* AI credits are sold in packs of **10,000 credits**
* Topup credits never expire and roll over to the next month
Spend draws from your recurring allowance first, then from topup credits.
## Running Out of Credits
When your balance is overdrawn, the Credit Usage page warns you and new AI calls are blocked until you top up. Everything else in Periskope — chats, tickets, bulk messages, automation rules that don't use AI — continues to work as normal.
To restore AI features, either purchase a topup pack or wait for your monthly credits to reset on your billing date.
# Chat List Bulk Actions
Source: https://docs.periskope.app/features/bulk-actions
If you're managing hundreds of WhatsApp chats, updating them one by one — adding labels, archiving, or organising — just doesn't scale. With Bulk Actions in Periskope, you can select multiple chats and make changes across all of them in seconds.
***
## Overview
Bulk Actions are available directly from the Chat List. Once you select one or more chats, a toolbar appears at the bottom of the screen with everything you need — from updating labels to exporting your chat list.
Whether you're doing a routine cleanup, onboarding a new team member, or responding to a sudden influx of conversations, Bulk Actions let you manage your entire workspace without touching each chat individually.
***
## Selecting Chats
### 1. Go to the Chat List
Head over to **Chat List** from the left sidebar.
***
### 2. Select chats
You have two ways to select chats:
* Click the **checkbox at the top** to select all chats at once
* Or tick **individual chats** one by one to select only the ones you need
Once at least one chat is selected, the bulk action toolbar appears at the bottom of the screen.
***
## Bulk Action Toolbar
The toolbar is always visible at the bottom of the screen whenever chats are selected. It gives you access to four main actions — **Update Chats**, **Group Actions**, **Upload Labels / Properties**, and **Export**.
***
## Update Chats
Click **Update Chats** to apply changes across all selected chats at once. You'll get a range of options:
| Action | What it does |
| :- | :- |
| Add labels | Apply one or more labels to all selected chats |
| Remove labels | Strip labels off all selected chats |
| Mark as read | Mark all selected chats as read |
| Mark as unread | Mark all selected chats as unread |
| Pin chats | Pin selected chats to the top of your list |
| Archive chats | Archive selected chats to keep your inbox clean |
| Activate AI Agent | Turn on the AI Agent across all selected chats |
| Activate AI Flagging | Enable AI flagging across all selected chats |
Select what you need and apply it — the changes take effect across all selected chats instantly.
> **Tip:** Use **Activate AI Agent** in bulk when you want to hand off a large set of conversations to the AI — for example, after a busy period when your team needs to catch up.
***
## Group Actions
If you've selected group chats, click **Group Actions** to add contacts to those groups in bulk.
1. Click **Group Actions** in the toolbar
2. Search for a contact by name or phone number
3. Click **Add**
The contact is added to all selected group chats at once — no need to go into each group individually.
***
## Upload Labels and Properties
Click **Upload Labels / Properties** to upload labels and custom properties across your selected chats in one go.
This is useful when you have a prepared list of data — for example, after importing a batch of new contacts — and want to apply labels or fill in custom property values across multiple chats at once without doing it manually.
***
## Export
Need a copy of your chat list? Click **Export** and choose how you'd like to receive it:
* **Download immediately** — the file downloads straight to your device
* **Send to email** — the export is sent to your registered email address
This is useful for reporting, audits, or sharing chat data with stakeholders outside of Periskope.
***
## Best Practices
**Use bulk select for routine maintenance** — Set aside time regularly to bulk-label, archive, or pin chats so your inbox stays organised and your team always knows what to focus on.
**Combine filters with bulk actions** — Filter your chat list first — by label, assigned member, or status — and then select all to apply bulk actions only to the relevant subset of chats. This keeps changes precise and avoids affecting chats you didn't intend to update.
**Use bulk AI activation strategically** — Activating the AI Agent across many chats at once is powerful, but make sure your knowledge base and tools are set up correctly before doing so at scale.
**Export regularly for reporting** — Use the Export feature to keep records of your chat list over time. This is especially useful for tracking how your conversation volume grows or for sharing updates with your team.
**Clean up labels in bulk** — If a campaign or project is over, use Remove Labels in bulk to keep your label system clean and meaningful.
***
# Sending a Bulk Message
Source: https://docs.periskope.app/features/bulk-message
Guide to send bulk messages to multiple WhatsApp groups & 1:1 chats with custom text, video, images - instantly or scheduled for a specific date and time.
## Overview
Periskope enables you to send bulk messages to multiple WhatsApp groups and 1:1 chats. Formats supported include text, links, images, documents, videos, and more. You can send immediately or schedule for a specific date and time. To set up messages that go out automatically on a recurring cadence, see [Repeating Bulk Messages](/features/bulk-message-repeating).
## Sending A Bulk Message
Follow these steps to send a bulk message:
Clicking `Add Chats` opens a dropdown with three options:
* **Select chats** - opens a modal where you can search and pick chats from your existing contacts.
* **Upload numbers / chat IDs** - upload a CSV of phone numbers to reach contacts not yet in your chat list.
* **Select from saved chat lists** - load a previously saved group of contacts instantly.
Alternatively, you can upload a CSV of contacts you want to send a bulk message to.
Use the phone picker on the right side of the toolbar to choose which of your WhatsApp numbers to send from. You can select one or multiple phones. Periskope handles the routing automatically - no need to know which contacts exist on which phone.
Select **Any phone** to let Periskope pick the most suitable number for each contact automatically.
If a contact cannot be reached from any of your selected phones, they will be flagged as a faulty chat before you send - giving you a chance to remove them from the list.
Write your message in the Draft Message section. You can include text, emojis, images, videos, documents, and variables.
To reuse a previously saved message, select it from the template picker.
Once you have a message you want to reuse, click `Save template` to save it for future broadcasts.
Click **Preview & Send** and choose a delivery mode:
* **Send now** - sends the broadcast immediately.
* **Schedule once** - pick a date and time to send the message once.
You can also set the **delay between messages** — the number of seconds Periskope waits before sending to the next contact. A longer delay reduces the chance of hitting WhatsApp rate limits.
To send on a recurring daily, weekly, or monthly cadence, see [Repeating Bulk Messages](/features/bulk-message-repeating).
Once confirmed, the broadcast runs in the background. You can track the live status of each message in the Bulk messages logs screen.
## Scheduled Broadcasts
You can view all one-time scheduled broadcasts from `Bulk messages > Scheduled messages > One time`. Each entry shows the scheduled send time, message preview, and recipient count.
To set up recurring broadcasts that run automatically, see [Repeating Bulk Messages](/features/bulk-message-repeating).
For information on message credits, see [Broadcast Credits](/features/bulk-message-credits).
# Broadcast Credits
Source: https://docs.periskope.app/features/bulk-message-credits
Understand how broadcast credits work, how many you get each month, and how to top up when you need more.
## Overview
Each message sent through bulk messaging consumes one credit from your account. Credits are separate from your regular WhatsApp usage and apply only to bulk message sends.
## Monthly Credits
* You receive **3,000 credits per user + additional phone** in your workspace every month
* You do not receive credits for the first free phone in your workspace
* Credits reset on your monthly billing date
**Example:** If you have 5 users, you receive 15,000 credits per month.
## Topup Credits
If you run out of monthly credits, you can purchase additional topup credits.
* Navigate to `Settings > Manage Plans > Topup Credits`
* Topup credits cost **\$0.006 (0.6 cents) per message**
* Topup credits never expire and roll over to the next month
Monthly credits are always used first before consuming any topup credits you've purchased.
# Logs
Source: https://docs.periskope.app/features/bulk-message-logs
View bulk message logs, stop ongoing broadcasts, retry failed messages, and duplicate previous broadcasts.
## Viewing Bulk Message Logs
The bulk message logs screen provides a comprehensive view of all bulk message operations, both past and ongoing.
Access this screen by going to `Bulk messages > Logs`. Here's what you can do:
1. **View All Broadcast Operations**: See a list of all bulk message operations you have conducted or that are currently in progress. Each entry shows the broadcast status, total chats, and counts for successful, failed, and pending messages.
2. **Detailed Broadcast Information**: Click on any log entry to open a detailed view of that broadcast. This includes:
* Total chats, success count, failed count, pending count
* Delivered and read percentages
* Timestamp and who performed the broadcast
* A per-chat table showing the status of every individual message, which you can filter by status (success, failed, pending)
## Stopping an Ongoing Broadcast
If you need to halt a bulk message operation that is currently in progress, you can stop it from the logs screen.
Go to `Bulk messages > Logs` where you can see the status of all your ongoing and past broadcasts.
Locate the ongoing broadcast, click the three-dot menu (⋯) on the right, and select `Stop sending`. This immediately halts processing of any remaining messages in the queue.
Stopping a broadcast will not recall or unsend messages that have already been sent. It only prevents pending messages from going out.
## Retrying Failed Messages
If some messages in a broadcast failed to deliver, you can retry just those contacts without resending to everyone else.
Go to `Bulk messages > Logs`.
Locate the broadcast with failed messages, click the three-dot menu (⋯) on the right, and select `Retry failed`. This creates a new send operation targeting only the contacts that failed — recipients who already received the message will not be messaged again.
Retrying a broadcast only sends to contacts where delivery failed. Successful and pending messages from the original broadcast are not affected.
## Duplicating a Broadcast
You can duplicate any previous broadcast to instantly use it as a starting point for a new one — keeping the same message, contact list, and settings.
Go to `Bulk messages > Logs`.
Find the broadcast you want to reuse and click the `Duplicate` button from the actions menu. This opens the new broadcast flow pre-filled with the original broadcast's settings, which you can adjust before sending.
# Repeating Bulk Messages
Source: https://docs.periskope.app/features/bulk-message-repeating
Set up repeating bulk messages that go out automatically on a daily, weekly, or monthly schedule.
## Overview
Repeating bulk messages let you set a broadcast once and have it go out automatically on a recurring schedule — daily, weekly, or monthly. This is useful for regular updates, reminders, or any message you send on a fixed cadence.
## Setting Up a Repeating Broadcast
Select your contacts and draft your message as you normally would. See [Sending a Bulk Message](/features/bulk-message) for the full send flow.
In the delivery mode screen, choose **Schedule repeating broadcasts**. Set the cadence:
* **Daily** — sends every day at the specified time
* **Weekly** — sends on a chosen day of the week
* **Monthly** — sends on a chosen date each month
Also set the **delay between messages** to control the gap between each recipient's message and reduce the risk of hitting WhatsApp rate limits.
Once confirmed, Periskope runs the broadcast automatically at the scheduled time. You can monitor each run from the Logs screen.
## Managing Repeating Broadcasts
Go to `Bulk messages > Scheduled messages > Repeating` to see all active recurring series.
Each entry shows:
* The next scheduled run date
* The cadence (daily / weekly / monthly)
* A preview of the message
From this screen you can:
* **Edit** — update the message, contacts, or schedule
* **Pause** — temporarily stop the series without deleting it
* **Resume** — restart a paused series
* **Delete** — permanently remove the recurring series
Pausing a series does not affect runs that have already been sent. It only prevents future runs from going out.
# Saved Chat Lists
Source: https://docs.periskope.app/features/bulk-message-saved-chat-lists
Save a list of groups and contacts under a name and reload them instantly when creating any future broadcast.
## Overview
Saved chat lists let you save a list of group and contacts under a name and load them instantly when creating any future broadcast — without re-selecting contacts each time. This is especially useful for recurring sends to the same audience.
## Saving a Chat List
On the new broadcast page, select the contacts you want to include using the `Add Chats` button.
Click the save icon in the toolbar and enter a name for the list.
## Using a Saved Chat List
When creating a new broadcast, click `Add Chats` → `Select from saved chat lists` and pick the list you want to load. All contacts from the list will be added instantly.
## Managing Saved Chat Lists
Go to `Bulk messages > Saved chat lists` to view, rename, edit, or delete any of your saved lists.
# Variables & Message Templates
Source: https://docs.periskope.app/features/bulk-message-variables-templates
Personalise bulk messages with per-contact variables and save reusable message templates for future broadcasts.
Message templates in Periskope are not related to WhatsApp Business API templates and do not require any prior approval.
## Variables
Variables let you personalize a bulk message for each recipient — inserting values like a contact's name, company, or any custom field into the message text. You can see exactly what each contact will receive in a live preview before you send.
### Adding Variables to a Message
Go to `Bulk messages > New bulk message`, select your contacts, and proceed to the Draft Message step.
Click the `{}` button in the message toolbar, or type `{` directly in the message body. Enter a name for the variable and a fallback value. The fallback is used for any contact where you leave the field empty.
After creating a variable, insert it by selecting it from the pop-up menu that appears when you type `{`.
Click `Next Step` to open the Fill Variables screen. Each contact appears as a row in the table — fill in variable values directly.
You can also fill values using a CSV. Download the CSV from the top right corner, fill in values using Google Sheets or Excel, then upload it back.
Do not modify the columns or add/remove rows in the downloaded CSV. If you need to add variables or chats, make those changes in the table first and download a new CSV.
Click through each contact in the preview panel to see exactly how the final message will look for that recipient, with all variables replaced by their actual values.
Once happy with the preview, choose a delivery mode and send. See [Sending a Bulk Message](/features/bulk-message) for delivery options.
***
## Message Templates
Message templates let you save a drafted message — including variables and attachments — and load it instantly in any future broadcast.
### Saving a Template
Write your message in the Draft Message section. You can include text, variables, images, videos, and other attachments.
Click the `Save template` button at the top of the Draft Message screen.
Enter a descriptive name so you can identify it easily later.
### Using a Template
When drafting a new broadcast, click the template picker to load a previously saved message. The message content, variables, and any attachments will be pre-filled.
### Duplicating a Template
You can duplicate an existing template from the template list to create a variation without modifying the original.
# Custom Properties
Source: https://docs.periskope.app/features/custom-properties
Create custom fields to organise and track information across your WhatsApp chats and groups.
***
## Overview
Custom Properties allow you to add additional data fields to your WhatsApp chats and tickets in Periskope. These properties appear in the **Properties tab** of the right side panel in any chat or ticket, enabling your team to capture and view important information for each conversation.
Properties are organised into **sections**, and you can create different properties for chats and tickets independently.
## Setting Up Custom Properties
### 1. Go to Settings → Custom Properties
Go to **Settings** from the left sidebar and click **Custom Properties** under the Organisation section.
***
### 2. Select the Chat or Ticket tab
You'll see two tabs at the top — **Chat** and **Ticket**. Select the tab depending on where you want the property to appear.
You'll see existing sections like **Default**, which already includes properties like Org ID, Org Name, Plan, and more.
***
### 3. Create a new section
Properties are organised into sections. To create one:
1. Click **+ New Section** in the top right
2. Give the section a name — for example, "Tax Info" or "Account Details"
***
### 4. Add a property to the section
1. Click on the section to open it
2. Click **+ Add New Property**
3. Enter a property name
4. Select a property type
5. Configure any additional settings based on the type selected
6. Click **Create Property**
Your property is now available across all chats or tickets in your workspace.
> **Note:** For tickets, you can mark certain properties as **mandatory** — ensuring your team always captures critical information before closing a ticket.
***
## Types of Custom Properties
Periskope offers six property types to cover different business needs:
| Type | What it's for |
| :- | :- |
| Text | Free-form information — names, notes, account details |
| Date | Date picker — renewal dates, sign-up dates |
| File Upload | Attach files or documents directly to a chat or ticket |
| Single-Select Dropdown | Pick one option from a predefined list |
| Multi-Select Dropdown | Pick multiple options from a predefined list |
| Dependent Dropdown | Hierarchical selection — up to three levels deep |
***
## Viewing and Filling in Custom Properties in a Chat
Once properties are created, your team can view and fill them in from any chat or ticket.
1. Open any chat
2. In the right-side panel, click the **Properties** tab
3. You'll see all your sections listed — like Tax Info, ARR, or any custom ones you've created
4. Click any field to fill it in or update it
> **Tip:** Custom properties filled in here — like `org_id` — can also be used by the Org Assistant to look up customer details and run Custom Tool actions without you needing to open the chat.
***
## Managing Custom Properties
### Moving properties between sections
You can move a property from one section to another at any time to reorganise your structure.
### Reordering and deleting sections and properties
Sections and properties can be reordered or deleted as your needs change.
### Filtering chats and tickets by custom properties
You can filter your chat or ticket inbox based on custom property values — for example, showing only chats where Plan is "Enterprise" or where a specific dropdown value is selected.
***
## Best Practices
**Keep it organised** — Group related properties into logical sections so your team can find what they need quickly.
**Use clear naming** — Make property names self-explanatory so there's no confusion about what to fill in.
**Start with essentials** — Begin with the most important properties and add more as needed, rather than creating everything at once.
**Review regularly** — Periodically check your properties to make sure they're still relevant and remove any that aren't being used.
**Train your team** — Make sure everyone knows how and when to fill in custom properties, especially any that are marked mandatory for tickets.
***
# Custom Properties for Tickets
Source: https://docs.periskope.app/features/custom-properties-for-tickets
Want to track extra details against every support issue — like urgency, product category, or resolution type? Custom Properties for Tickets in Periskope let you add any field your team needs, directly inside the ticket.
***
## Overview
Ticket Custom Properties allow you to add additional data fields to your tickets in Periskope. These properties appear inside the **ticket detail view**, enabling your team to capture and view important information for every issue they handle.
Properties are organised into **sections**, and ticket properties are configured independently from chat properties — so you can tailor each one to how your team works.
***
## Setting Up Ticket Custom Properties
### 1. Go to Settings → Custom Properties
Go to **Settings** from the left sidebar and click **Custom Properties** under the Organisation section.
***
### 2. Click on the Ticket tab
At the top of the page, click the **Ticket** tab to switch to ticket properties.
***
### 3. Create a new section
Properties are organised into sections. To create one:
1. Click **+ New Section** in the top right
2. Give the section a name — for example, "Issue Details" or "Resolution Info"
***
### 4. Add a property to the section
1. Click on the section to open it
2. Click **+ Add New Property**
3. Enter a property name
4. Select a property type
5. Configure any additional settings based on the type selected
6. Click **Create Property**
Your property is now available across all tickets in your workspace.
> **Note:** For tickets, you can mark certain properties as **mandatory** — ensuring your team always captures critical information before a ticket can be closed.
***
## Types of Custom Properties
Periskope offers six property types to cover different business needs:
| Type | What it's for |
| :- | :- |
| Text | Free-form information — notes, descriptions, account details |
| Date | Date picker — due dates, escalation dates, follow-up dates |
| File Upload | Attach files or documents directly to a ticket |
| Single-Select Dropdown | Pick one option from a predefined list |
| Multi-Select Dropdown | Pick multiple options from a predefined list |
| Dependent Dropdown | Hierarchical selection — up to three levels deep |
***
### Dependent Dropdown — Example
The dependent dropdown is the most advanced type. Each selection at one level determines the available options at the next — useful when you need to track layered information without free-form text errors.
**Example — Product Selection:**
* **Level 1 (Category):** Electronics, Appliances, Furniture
* **Level 2 (Product):** If "Electronics" is selected → Smartphones, Laptops, TVs
* **Level 3 (Model):** If "Smartphones" is selected → Model X, Model Y, Model Z
***
## Viewing Ticket Properties
Once properties are created, your team can view and fill them in from inside any ticket.
1. Open any ticket
2. You'll see all your custom sections and fields listed in the ticket detail view
3. Click any field to fill it in or update it
For example, you can:
* Mark the urgency as **High**, **Medium**, or **Low**
* Add a relevant **date**
* **Add comments** directly inside the ticket
***
## Managing Custom Properties
### Moving properties between sections
You can move a property from one section to another at any time to reorganise your structure.
### Reordering and deleting sections and properties
Sections and properties can be reordered or deleted as your needs change.
### Filtering tickets by custom properties
You can filter your ticket inbox based on custom property values — for example, showing only tickets where urgency is "High" or where a specific dropdown value is selected.
***
## Best Practices
**Keep it organised** — Group related properties into logical sections so your team can find what they need quickly.
**Use clear naming** — Make property names self-explanatory so there's no confusion about what to fill in.
**Start with essentials** — Begin with the most important properties and add more as needed, rather than creating everything at once.
**Use mandatory fields** — Mark critical properties as mandatory to ensure your team never closes a ticket without capturing the information you need.
**Review regularly** — Periodically check your properties to make sure they're still relevant and remove any that aren't being used.
**Train your team** — Make sure everyone knows how and when to fill in ticket properties, especially any that are marked mandatory.
***
# Data Exports
Source: https://docs.periskope.app/features/export-data
Export chat data, group members, contact attributes and files
## Overview
Periskope provides comprehensive data export capabilities that allow you to download various types of data from your account. You can export chat data, group member information, contact attributes, message history, ticket information, phone data, and more.
## Analytics Data Exports
The primary method to access all export options in Periskope is through the Analytics section:
1. Navigate to the left sidebar menu
2. Click on **Analytics**
3. Select **Data Exports**
This will take you to the Data Exports page where you can select from multiple export types.
## Available Export Types
From the Analytics > Data Exports page, you can access the following export types:
* **Chats Export:** Export complete chat history including timestamps and metadata. Choose between group and individual chats.
* **Members Export:** Export member data including roles, permissions, and account details for team management and audits.
* **Messages Export:** Export detailed message data including content, timestamps, metadata, and flagged message filters.
* **Private Notes Export:** Export private notes added to chats, including the note content, author, timestamps, mentioned members, and media attachments.
* **Tickets Export:** Export ticket information such as status, priority, assignee, and resolution details for support tracking.
* **Phones Export:** Export phone number data and associated metadata for all connected and disconnected numbers.
* **Chat Actions Export:** Export history of chat actions like member additions, removals, and role changes for audit trails.
* **Chat Audit Logs Export:** Export the change history of chats — assignee changes, label changes, custom property updates, name and image changes, and archive actions — with old and new values for each change. Useful for tracking chat journeys and audits.
## Export Process
For all export types in the Analytics > Data Exports section:
1. Select the radio button next to the export type you want
2. Click the "Export" button at the bottom of the page
3. A modal will open up to select date range, export format and export type for your data. It would also include some other filters
4. If you click on `Download Now`, the file will be downloaded automatically in CSV format. Here the file could have at most 20,000 rows of data
5. If you click on `Via Mail`, the file will be send over to you via email. It could take some time to reach you as the file could have at most 100,000 rows of data
## Additional Export Methods
In addition to the Analytics > Data Exports section, Periskope offers several other ways to export specific data:
### 1. Bulk Export from Chat List
You can export group member data in bulk directly from the chat list:
1. Navigate to the Chat List Screen
2. Select multiple chats and groups that you would like to export
3. Click on `Export` button from the select island shown at the botton of the screen
Chat ID, Chat Name, Chat Type, Org Phone, and other details will be downloaded in a XLSX format.
### 2. Bulk Export from Tickets Screen
You can export ticket data in bulk from the Tickets screen:
1. Navigate to the Tickets section
2. Select the tickets you want to export
3. An island will pop up at the bottom of the screen, from there go to `Update Tickets` and select `Export Tickets`
### 3. Export Individual Chat Data
You can export data for a single chat directly from the chat interface:
1. Navigate to the Chats
2. Open the specific chat you want to export
3. Click on `Export Chat` on the sidepanel
# Labels
Source: https://docs.periskope.app/features/labels
Create and use labels to organise and filter chats, contacts, and tickets across your workspace.
## Overview
Labels help you categorise and manage chats, contacts, and tickets. Apply multiple labels to any item, filter your inbox by label, and use labels to control which chats team members can access.
***
## Creating a Label
Labels are created from your organisation settings.
1. Go to **Settings** from the left sidebar
2. Under the **Organisation** section, click **Labels**
3. Click **Create Chat Label**
4. Enter a **name** and choose a **colour**
5. Click **Save Label**
You can also create labels on the fly — type a new label name anywhere labels are applied and click **Create label**.
***
## Applying Labels
### To a Chat
Open any chat and click **Add label** in the right-hand panel. You can apply multiple labels to the same chat.
### To a Contact
Navigate to **Contacts**, select a contact, and click **Add label** on the right-hand panel.
### To a Ticket
Navigate to **Tickets**, select a ticket, and click **Add label** on the right-hand panel.
***
## Filtering by Label
Once labels are applied, use them to filter your inbox.
1. Go to **Chats**
2. Click the **Filter** icon at the top of the chat list
3. Under **Filter condition**, select **Labels**
4. Choose the label to filter by
Only chats with that label will appear — useful for focusing on a specific group like "VIP" or "Renewal".
***
## Managing Labels
Go to **Settings > Labels** to view, rename, or delete any label. Click on a label to edit it.
***
## Using Labels with the Org Assistant
Instead of updating chats one by one, instruct the Org Assistant to act on all chats with a specific label at once.
**Example prompts:**
```text theme={null}
Assign all chats labelled "Demo" to Rahul.
```
```text theme={null}
Send a private note to all chats labelled "Renewal" saying "Follow up before Friday."
```
```text theme={null}
Add the label "Escalated" to all open chats assigned to Priya.
```
# Media Privacy
Source: https://docs.periskope.app/features/media-privacy
Serve WhatsApp media through secure Periskope URLs with organization-level access control and expiring links.
### **Overview**
Media files on Periskope (images, videos, audio, and documents) are now served through Periskope URLs (`https://api.periskope.app/app/media/...`) instead of direct Google Cloud Storage bucket links.
Previously, anyone with a media link could open it forever. With Media Privacy, you control who can access your organization's media and for how long — links can require authentication and expire automatically.
Media Privacy is **off by default**. Until you enable it, media URLs simply moved to the new Periskope domain and remain publicly accessible — nothing else changes for you.
***
### **How Media Access Works**
When a media URL is opened, Periskope checks your organization's privacy setting and then redirects to a short-lived storage URL that serves the actual file:
1. **In the Periskope app** — access is granted automatically through a secure session cookie. Your team never has to do anything.
2. **Outside the app** (APIs, webhooks, integrations, shared links) — if Media Privacy is enabled, URLs carry a signed access token that expires after your configured duration. Without a valid token, the request is rejected.
If Media Privacy is disabled, media URLs are served without any authentication.
***
### **Enabling Media Privacy**
* Go to **Settings → Config** and scroll to the **Media Privacy** setting.
* Turn on the **Media Privacy** toggle.
* Once enabled, all media links sent via API responses, webhooks, and integrations include an expiring access token.
***
### **Configuring Link Expiry**
With Media Privacy enabled, choose how long external media links stay valid under **Link Expiry**:
* Options range from **10 minutes** to **7 days** (default: **24 hours**).
* The expiry applies to links delivered via APIs, webhooks, integrations, and the copy-link option in chats.
* After a link expires, fetch a fresh one with the [Migrate Media URL API](/api-reference/media/migrate-url) or by re-fetching the message.
***
### **What Changes for APIs, Webhooks & Integrations**
* **API responses** and **webhook payloads** now return `api.periskope.app/app/media/...` URLs instead of `storage.googleapis.com` URLs.
* **Integrations** (HubSpot, Zoho, Freshdesk, Google Sheets, Zapier, and others) receive the same new URLs automatically — no reconfiguration needed.
* If Media Privacy is enabled, download media within your configured expiry window instead of storing links long-term. Store the message ID and generate a fresh link when needed.
***
### **Migrating Old Media URLs**
If you have stored old `storage.googleapis.com` URLs in your systems, convert them to the new format using the Media APIs:
* [Migrate Media URL](/api-reference/media/migrate-url) — convert a single URL.
* [Migrate Media URLs (Batch)](/api-reference/media/migrate-url-batch) — convert up to 1,000 URLs in one request.
Both endpoints also refresh expired Periskope media links with a new access token.
Direct Google Cloud Storage URLs are deprecated and will stop working in a future phase of the rollout. Migrate any stored URLs to the new format now to avoid broken links.
***
### **FAQs**
No. The app handles authentication automatically for your team, and Media Privacy stays off unless you enable it.
Old bucket URLs continue to work during the rollout, but they are deprecated. Use the migration API to convert stored URLs to the new format.
A **401** means the link's access token is missing or expired — generate a fresh link via the migration API. A **403** means the media belongs to a different organization than the API key used.
No. This only affects media links served by Periskope (app, APIs, webhooks, integrations). Media delivery on WhatsApp itself is unchanged.
# Multi-Number Inbox
Source: https://docs.periskope.app/features/multi-number-inbox
Connect and manage multiple WhatsApp numbers from a single dashboard
## Overview
Multi-number inbox allows you to connect and manage multiple WhatsApp numbers from your Periskope account. This is most valuable for sales, customer service, logistics and other verticals where managers may need better visibility into the WhatsApp activity of their teams
## Connecting multiple phones
Admins can connect multiple phones from settings > phones. Please note that while one phone is included in each base plan, each additional phone instance incurs a seperate charge.
## Viewing chats across connected phones
WhatsApp chats and groups across all connected numbers will be visible in the chats screen. The organization phone that is part of each chat/group is visible below the chat summary on the left. In case multiple phones are present in a chat, both the phone numbers will be visible.
## Replying to chats across connected phones
When replying to any chat, the connected org number is shown in the reply box. In case multiple org numbers are part of a chat, a user can choose the number they reply from using the dropdown at the bottom right.
## Identifying who replies from Periskope
The email id of the person replying is shown below every message on Periskope. This allows you to identify who within Periskope has replied to a message (while on WhatsApp it will simply be a message from the respective org number)
# Number Masking & Privacy
Source: https://docs.periskope.app/features/number-masking-privacy
Give team members access to manage WhatsApp chats without exposing customer phone numbers or your full inbox.
### **Introduction**
Learn how to keep your business number and customer contact details completely hidden from agents and contractors while they manage your chats.
### **Overview**
Traditionally, giving team members access meant revealing the phone number and giving them the power to take contacts with them. Periskope allows you to keep your business number and contact details completely hidden from agents and contractors while they manage your chats.
Before enabling number masking, make sure your agents are invited as **Members** with label-based chat access. See [Team Access & Roles](/features/team-access-roles) for setup.
***
### **Enabling Number Masking**
This ensures that while the agent can see names and conversation history, they cannot see the actual phone digits.
* Go to **Config** and scroll to **Privacy and Display**.
* Ensure the **Masking Toggles** are active.
* The actual phone digits will remain invisible to the agent, protecting your client database.
***
### **Why Use Number Masking?**
* **Protect Your Database:** Prevent agents or external help from taking your contacts with them.
* **Professional Branding:** Customers receive a consistent experience while you maintain absolute control.
* **Workflow Efficiency:** When a lead needs attention, simply apply the label, and it pops up on the agent's screen instantly — fully masked and ready for action.
### **PROTECT YOUR ASSETS**
By masking your numbers and using label-based access, you aren't just protecting your privacy — you're building a secure, professional brand. Head to your **Team Settings** to ensure your client numbers are safe and your database remains under your control.
# Private Notes
Source: https://docs.periskope.app/features/private-note
When a customer conversation needs another teammate's attention, Private Notes let you leave internal messages directly inside a chat — visible only to your team, never to the customer.
***
## Creating a Private Note
Open any chat. At the bottom, you'll see two tabs — **WhatsApp** and **Private Note**. Click **Private Note**.
> **Note:** Anything you send in Private Note mode is only visible to your team — not the customer.
***
## Adding Context
Before tagging someone, add context so your teammate knows exactly what's going on without reading the entire conversation.
For example:
```text theme={null}
This customer is asking about the AI features of Periskope. Can you take a look at this?
```
***
## Tagging a Teammate
Type `@` followed by their name to tag them. For example:
```text theme={null}
@Rohosen, this customer is asking about the AI features. Can you take a look at this?
```
Once sent, the note appears inside the chat — your team can see it, the customer never will.
***
## Why This Works
Your teammate gets tagged, opens the chat, reads the conversation and your note, and takes over straight away — no Slack, no email, no lost context. Everything stays in one place.
***
# Quick Replies
Source: https://docs.periskope.app/features/quick-replies
Does your team find themselves typing out the same responses over and over again? With Quick Replies in Periskope, you can create shortcuts for your most common messages — and send them in seconds.
***
## Setting Up a Quick Reply
### 1. Go to Settings → Quick Replies
Go to **Settings** from the left sidebar and click **Quick Replies** under the Organisation section.
***
### 2. Create a new Quick Reply
Click **Create Quick Reply** in the top right.
***
### 3. Enter a command
Enter a **command** — for example, `/call`. This is the shortcut your team will type in the message box to trigger the quick reply.
> **Tip:** Keep commands short and memorable — your team will be typing these in the middle of live conversations, so something like `/call`, `/pricing`, or `/refund` works better than something long.
***
### 4. Write the message
In the **Compose** section, type the message you want to send. For example:
```text theme={null}
Feel free to book a demo call from here — [your demo link]
```
Once done, click **Save**.
Your quick reply is now available to every member of your team across all chats.
***
## Using a Quick Reply in a Chat
1. Open any chat
2. In the message box, type your command — for example, `/call`
3. The quick reply appears instantly as a suggestion
4. Click it to populate the message box
5. Hit send
The customer receives your full message — without your team having to type a single word.
***
## Best Practices
**Create replies for your most common messages** — Think about what your team types repeatedly every day: demo links, pricing info, refund policies, onboarding steps. Each one is a good candidate for a quick reply.
**Use clear command names** — Make commands intuitive so your team doesn't have to remember obscure shortcuts. `/pricing`, `/demo`, `/support` are all easy to recall.
**Keep messages up to date** — If a link changes or your messaging evolves, go back to Settings → Quick Replies and update the relevant entries so your team is always sending the right thing.
**Train your team** — Make sure everyone knows which quick replies exist and what commands to use. A shared list in your team's internal notes can help.
***
# Scheduled & Recurring Messages
Source: https://docs.periskope.app/features/recurring-scheduled-messages
Schedule one-time and recurring messages to be sent automatically to your customers
## Overview
Periskope allows you to schedule messages to be sent at a future date and time. You can also set up recurring scheduled messages that repeat at regular intervals. This feature is perfect for sending reminders, follow-ups, and regular updates to your customers without manual intervention.
## Types of Scheduled Messages
### One-time Scheduled Messages
Messages that are scheduled to be sent once at a specific date and time.
### Recurring Scheduled Messages
Messages that are scheduled to be sent repeatedly at regular intervals (daily, weekly, monthly, etc.).
## One-time Scheduled Messages
One-time scheduled messages allow you to compose a message now and have it delivered at a specific date and time in the future. This is ideal for appointment reminders, follow-ups, or any time-sensitive communication.
### Steps to Schedule a One-time Message
In any WhatsApp chat, compose your message as usual in the message input box.
Click on the schedule icon (clock) next to the send button to open the scheduling options.
1. Select the date for your message using the calendar picker
2. Set the specific time for delivery
3. Ensure the "Repeat" toggle is turned OFF for a one-time message
4. Click "Schedule" to confirm
## Recurring Scheduled Messages
Recurring scheduled messages allow you to set up messages that will be sent automatically at regular intervals. This is perfect for periodic reminders, regular updates, or any communication that needs to happen on a consistent schedule.
### Steps to Setup a Recurring Message
In any WhatsApp chat, compose your message as usual in the message input box.
Click on the schedule icon (clock) next to the send button to open the scheduling options.
1. Click on the Repeat option to make this message recurring.
2. Select the start date and time for your recurring message
3. Choose your preferred frequency:
* Daily: Specific days of the week
* Weekly: Choose one day of the week
* Monthly: Select specific date(s) of the month
4. Choose your gap - select a number in font of the frequency
to set how often you want to repeat the message in the specified interval.
* e.g. Once every two weeks, Once every day
5. Choose allowed days (daily):
* For messages repeating daily, uncheck the box for the days you do not want the message to deliver.
6. Set an end date (optional) or leave it open-ended
7. Click "Schedule message" to confirm
## Managing Scheduled Messages
Both one-time and recurring scheduled messages can be managed through the Scheduled Message History interface.
Click on the scheduled message history icon next to the schedule button to view all your scheduled messages for the current chat.
Click the settings icon (gear) on any message to edit it.
In the Scheduled Message History modal, you can:
1. View all pending scheduled messages
2. See which messages are one-time or recurring
3. Modify the schedule time, frequency, or message content
4. Delete scheduled messages that are no longer needed
To see a complete history of all scheduled messages across all chats:
1. Navigate to Logs > Scheduled Logs in the main menu
2. Filter by one-time or recurring messages
3. View delivery status, timestamps, and message details
## Best Practices for Scheduled Messages
* **Timing Consideration**: Be mindful of when you schedule your messages. Scheduling messages during business hours is recommended.
* **Frequency Management**: For recurring messages, be mindful of frequency to avoid spamming
# Team Access & Roles
Source: https://docs.periskope.app/features/team-access-roles
Invite team members, assign roles, manage chat access, and control agent availability across your workspace.
## Overview
A shared multi-agent inbox enables you to give access to multiple team members to manage, view and respond to messages without being on WhatsApp. This is most valuable for managing customer queries and support requests on WhatsApp groups & 1:1 chats.
## Inviting a team member
Navigate to Settings > Team and click on Invite team
Enter emails of members you would like to invite. If you want to invite multiple members, enter all email IDs seperated by commas.
You can invite users as either Admins
or Members
. Admins will have access to all WhatsApp chats and groups that that connected numbers are part of. Members will only have access to the chats or groups that you give them access to either at the time of inviting or later from the Chat List section.
This dropdown is only active when you want to invite a user as Member
. The member will have access to only those WhatsApp chats and groups that have the labels attached to it. Labels can be selected the dropdown at the time of invitation or later from the Chat List section.
## Viewing who has access to a specific group or chat
The dropdown on the top right of any group or chat will show all the users who have access to that group or chat. Admins by default have access to all chats and groups and will show as default selected in the drop down.
## Controlling Chat Access with Labels
Instead of giving a Member access to your entire inbox, use labels to filter exactly which chats they can see. The Member's inbox stays empty until you apply a matching label to a chat — giving you precise control over what they work on.
* Use the **Access to Chats** dropdown when inviting a Member.
* Select a specific label (e.g., "Contractor" or "Support").
* The Member will only see chats that have that label applied.
* To give them access to a new chat, simply add the label to it from the chat panel.
This approach also protects your data — Members cannot see your full contact list or phone numbers unless you explicitly expose them. See [Number Masking & Privacy](/features/number-masking-privacy) for more on hiding customer phone numbers from agents.
## Managing Agent Online/Offline Status and Shift Schedules
Periskope allows you to manage agent availability through both automated shift scheduling and real-time status controls. This helps ensure that chats and tickets are allocated only to agents who are currently available.
### Setting Agent Online/Offline Status
You can manually set an agent's status to control their availability for chat and ticket assignments:
#### For Individual Users:
Users can toggle their own status from the sidebar:
#### For Team Admins:
Admins can manage status for multiple team members at once:
1. Navigate to Settings > Team
2. Select one or more team members from the list
3. Click the "Action" dropdown button
4. Choose "Set Status" from the dropdown
5. Select either "Online" or "Offline" from the second-level dropdown
### Setting Agent Shift Schedules
Configure recurring work schedules for your team to automate availability:
1. Navigate to Settings > Team
2. Select one or more team members from the list
3. Click the "Action" dropdown button
4. Choose "Set Schedule" from the dropdown
5. In the shift timings modal:
* Select the appropriate timezone
* Set specific working hours for each day of the week
* Add up to three shifts per day if needed
* Click "Save" to apply the schedule
### How Agent Availability Affects Chat Routing
When using round-robin assignment in your routing rules, you can configure how agent availability is determined:
* **Consider shift times only**: Assigns chats based on the agent's configured schedule
* **Consider online/offline status only**: Assigns chats based on the agent's current manual status
* **Consider both shift and status**: Assigns chats only when both conditions are met (agent is within their shift time AND manually set to online)
## Viewing team level metrics
Team level metrics such as total replies, # of open tickets and average first response times are available in the Periskope dashboard and covered in detail in the [Workspace Metrics](/features/workspace-metrics) section
# Workspace Metrics
Source: https://docs.periskope.app/features/workspace-metrics
View and understand message, ticket, and team performance metrics across your Periskope workspace
## Overview
Once you have connected your WhatsApp numbers to Periskope, you can view and understand the metrics on the dashboard.
## Understanding the metrics
Periskope dashboard consists primarily of two sections:
1. **Metrics**: This section consists of the key metrics for your WhatsApp numbers and team.
2. **Connected Phones**: This section lists all the connected WhatsApp numbers. You can see the status of the phone and also perform actions on it.
The dashboard metrics section provides a summary of the key metrics for your WhatsApp numbers. Here's a quick overview of the metrics:
1. **All Chats**: The total number of chats that the connected WhatsApp number is part of.
2. **Unread Chats** : The total number of chats that are unread by the team members.
3. **Flagged chats**: Total number of chats that are **flagged as important** by AI and team members based on selected days filter.
4. **Tickets**: The number of tickets that are **open** and are **in progress**.
5. **Team**: The number of team members that are online.
To know more about your WhatsApp metrics navigate to the `Analytics` page by clicking the Analytics button on the left hand side of the side panel.
Metrics are divided into `three sections`:
#### 1. Message metrics 💬
Message metrics provide insights into your WhatsApp messages of your team. Here's a quick overview of the messages metrics:
1. **Messages statics over the selected time period**:
* **Active chats**: The total number of unique active chats.
* **Outgoing messages**: The total number of messages sent by your team members.
* **Incoming messages**: The total number of messages received by your WhatsApp number(s).
* **Flagged messages**: The total number of messages that are flagged as important by AI and team members.
* **Median first response time**: The median time taken by the team to respond to a message.
2. **Message Metrics Overview Graph**:
* Shows the number of flagged, incoming, outgoing and active chats over the selected time and filters applied.
3. **Team Message Metrics**:
* Shows you the list of all the members with their active chats, messages sent and flagged responses over the selected time period and filters applied.
You can filter out data based on your requirements. The default filter is set to Last 7 days with no labels selected.
#### 2. Ticket metrics 🏷️
Ticket metrics provide insights into the performance of your team members using a metric table. Here's a quick overview of the metrics:
1. **Tickets**:
* **Un-resolved Tickets**: The number of tickets that are open or in progress.
* **Open Tickets**: The number of tickets that are open and not resolved.
* **In progress**: The number of tickets that are in the process of being resolved.
* **Unassigned Tickets**: The number of tickets that are not assigned to any team member.
* **Average Resolution Time**: The average time taken to resolve/close a ticket.
2. **Tickets Graph History**:
* Shows the number of tickets created, closed and unresolved over a period of 7 days.
3. **Team Members Tickets Metrics**
* Shows the number of tickets assigned to each team member and the number of tickets resolved by each team member over the last 7 days.
#### 3. Team analytics 👥
Team metrics provide insights into the performance of your team members using a metric table. Here's a quick overview of the metrics:
1. **Chats assigned**: The total number of chats assigned to a team member.
2. **Messages sent**: The total number of messages sent by a team member.
3. **Open tickets**: The total number of open tickets assigned to a team member.
4. **Responses**: The total number of responses sent to flagged messages by a team member.
5. **Average response time**: The average time taken by a team member to respond to a flagged message.
6. **User uptime**: The total time (in hours) the user was online on the platform.
You can filter out data based on your requirements. The default filter is set to Last 7 days with no labels selected, you can also filter out by a specific chat/group.
For any queries or help, reach out to us [here](https://what.sapp.link/periskope)
# Best Practices
Source: https://docs.periskope.app/get-started/best-practices
Essential best practices and recommendations for safe WhatsApp outreach — behavior scores, warm numbers, unknown-number outreach, group additions, and restrictions
Periskope allows you to efficiently manage bulk actions, such as sending messages across multiple WhatsApp groups and 1:1 chats, or adding and removing users with a single click.
However, WhatsApp enforces strict policies against mass messaging and spam, which can lead to account suspensions or bans if not carefully managed. Periskope takes precautions by sending bulk messages with randomized delays to simulate natural messaging behavior, but ultimately, account status remains under WhatsApp's control.
To help reduce the risk of suspensions or bans, this article provides essential best practices and recommendations for safe WhatsApp outreach.
## How WhatsApp Judges Your Number: Behavior Scores
WhatsApp maintains an internal quality assessment of every number — often referred to as a **behavior score**. You cannot see this score directly, but almost every enforcement decision (rate limits, restrictions, bans) flows from it. Understanding what moves it is the foundation for everything else in this guide.
**Signals that improve your score:**
1. **Two-way conversations.** Replies are the strongest trust signal. A number that gets responses looks like a human; a number that only broadcasts looks like a bot.
2. **Contacts saving your number.** When recipients add you to their address book, WhatsApp treats your relationship as consensual.
3. **Account age and consistency.** Numbers with months of steady, moderate activity are trusted far more than new numbers or numbers with erratic spikes.
4. **Delivery and read rates.** Messages that get delivered, read, and answered indicate wanted communication.
5. **Group joins via invite links.** Voluntary joins signal that people want to hear from you.
**Signals that damage your score:**
1. **Blocks and spam reports.** The single most damaging signal. Just 3–5 reports in a short window can trigger enforcement.
2. **Messaging numbers that don't exist.** Sending to invalid or unregistered numbers is a classic spam-list fingerprint. WhatsApp sees that no real relationship could possibly exist.
3. **One-way blasting.** High send volume with near-zero replies.
4. **Mass direct group additions.** Adding people to groups without consent (see the [dedicated section below](#adding-numbers-directly-to-groups-is-a-spammy-action)).
5. **Identical message content.** Hundreds of copies of the same text, especially with links, look like a campaign — personalize with variables.
6. **Sudden behavior changes.** A quiet number that starts sending 200 messages a day, or creates 5 groups in an hour.
Behavior scores recover slowly and degrade quickly. A week of careful, conversational activity might undo one afternoon of aggressive blasting — so it is always cheaper to stay conservative than to rehabilitate a damaged number.
***
## What Can Trigger a WhatsApp Account Ban?
WhatsApp enforces strict policies against spam and suspicious activity. Violating these can result in account suspension or permanent ban. Here are the key triggers:
### 1. Using Very New Numbers to Connect and Send Messages
Newly registered numbers are particularly vulnerable to being flagged and blocked. The longer a number has been registered, the more "trustworthy" it appears to WhatsApp's algorithms.
**Recommendations:**
Before using a number for bulk messaging, send and receive messages with real users for a few days to establish legitimate activity. Follow our [Warming Up Numbers guide](https://docs.periskope.app/get-started/warmup-numbers/) for the full process.
Avoid scanning the WhatsApp QR code immediately after registering a new number. Waiting a day or more before connecting helps avoid suspicion.
Send 5-10 natural messages first with real users and wait some time before using the number for bulk activities.
### 2. Complaints About Spam
User complaints are the #1 reason for bans. Just 3-5 reports can trigger suspension. Receiving spam complaints is one of the main reasons WhatsApp blocks accounts. Users who report your number can quickly flag it as problematic, leading to potential bans.
**Recommendations to Minimize Spam Complaints:**
1. Start the conversation by asking a question. Getting the recipient to respond increases engagement and lowers the likelihood of being flagged as spam.
2. Include a line such as "Reply with STOP to unsubscribe" at the end of your message. This provides a convenient way for dissatisfied users to opt out without reporting you.
3. Tailor each message by addressing the recipient by name, making it feel more personal (e.g., "Hello, %client\_name%!").
4. Limit to 1-2 bulk messages per day per contact so the recipient does not feel that they are being spammed
5. Groups are typically safer environments for bulk messages (users joined voluntarily)
**Start Conversations Instantly on WhatsApp:**
Add a **"Chat on WhatsApp"** button to your website, landing page, or ads so customers can message you with one tap.\
You can also share a personalized WhatsApp link with a pre-filled greeting to make starting conversations effortless.
* Create a free WhatsApp button with [Periskope's Click-to-Chat Tool](https://tools.periskope.app/free-whatsapp-click-to-chat-button?utm_source=chatgpt.com)
* Generate personalized WhatsApp links using [WhatsApp Link Generator](https://what.sapp.link/?utm_source=chatgpt.com)
### 3. Suspicious Mass Activity
Sudden activity spikes appear bot-like and trigger automatic blocks. Sudden, high-volume activity can appear suspicious to WhatsApp's algorithms and may lead to a ban.
**Recommendations to Avoid Triggering Suspicious Activity Flags:**
If your number hasn't shown much activity previously, start small and build up progressively.
If your account has not previously created groups, suddenly creating multiple groups can appear unnatural. Space out group creation to avoid detection.
Adding many numbers to groups at once can trigger WhatsApp's spam detection. Add users judiciously to avoid appearing as spam. Space them out by 2-4 hours.
If you haven't messaged unfamiliar numbers before, avoid contacting a large volume of new recipients at once. Gradually increase messaging activity to build up a "safe" reputation.
Add max 15-20 contacts per group or per day when adding directly. This prevents appearing as spam and maintains account health
Monitor daily message volume and maintain consistent messaging patterns. Gradually increase activity to build a "safe" reputation without sudden spikes.
### 4. Unauthorized Automation Tools
WhatsApp blocks accounts using unapproved tools. Use only: WhatsApp Business API, WhatsApp Cloud API, or verified platforms like Periskope.
1. Avoid tools claiming to bypass WhatsApp restrictions
2. Don't use web scrapers or unverified bots
3. Use only official or WhatsApp-approved platforms
***
## Using Warm Numbers for Outreach
Warming a number (see the [step-by-step guide](https://docs.periskope.app/get-started/warmup-numbers/)) gets you a trusted asset. How you **deploy** that asset matters just as much:
Never run cold outreach from the number your team depends on for support, groups, or daily customer conversations. Keep a dedicated, warmed outreach number so that if enforcement ever hits it, your core business number is unaffected.
A number warmed for 10 days can handle modest outreach (20–40 new conversations/day), not campaign-scale sends. Treat warm-up as a license to *start*, not to blast. Scale weekly, not daily.
A warmed number that then does nothing but broadcast will cool off fast. Keep genuine two-way conversations running alongside outreach — replies, group participation, inbound handling. A healthy mix is at least one reply received for every 5–10 outbound conversations started.
If you have sustained outreach volume, spread it across 2–3 warm numbers rather than pushing one number to its limits. Warm replacements **before** you need them — warming takes 3–10 days, and a restriction can land overnight.
Track delivery rates, reply rates, and failed sends per number. A declining delivery rate is the earliest warning that a number's behavior score is slipping — reduce volume immediately rather than pushing through.
***
## Managing Outreach to Unknown Numbers
Messaging a number that has never talked to you is the highest-risk action on WhatsApp. Every unknown-number message is scored: no saved contact, no chat history, no prior relationship. Here's how to do it as safely as possible:
### Verify Numbers Before You Message Them
Sending messages to numbers that **aren't on WhatsApp at all** is one of the strongest spam fingerprints — real humans don't message numbers that don't exist, but purchased or scraped lists are full of them.
1. **Clean your lists.** Remove duplicates, malformed numbers, and landlines before importing.
2. **Prefer collected numbers over purchased lists.** Numbers gathered from sign-ups, events, or inbound chats are both consensual and near-certain to exist.
3. **Let Periskope verify for you.** Periskope checks whether a recipient exists on WhatsApp before dispatching a message to a new number, and fails the message instead of sending it blind — protecting your behavior score automatically. A failed message will show the reason (e.g. "Contact does not exist on WhatsApp") on the message's error indicator.
### Design the First Message for a Reply
Your first message to an unknown number decides whether you gain a trust signal (a reply) or a damage signal (ignored, blocked, or reported).
1. **Identify yourself and the context immediately** — "Hi %client\_name%, this is Priya from Acme — you signed up at our stall at TechExpo yesterday."
2. **Ask a question** the recipient can answer in one line. Getting a response is worth more to your score than ten delivered monologues.
3. **No links in the first message.** Links from unknown numbers are heavily associated with spam. Earn a reply first; share links second.
4. **Offer an exit** — "Reply STOP if you'd rather not hear from us." An unsubscribe costs you nothing; a report costs you the number.
### Pace and Sequence
1. **Cap new-contact conversations per day** — 15–20/day for a young number, scaling gradually for aged numbers. New-chat volume is measured separately from overall message volume.
2. **Spread sends across the day** rather than firing a batch in one minute. Periskope adds randomized delays automatically, but you should also avoid queuing your entire list at once.
3. **Stop-loss rule:** if a batch shows unusually low delivery or reply rates, pause the campaign — don't "finish the list." The list is the problem.
4. **Follow up only with responders.** Re-messaging people who ignored your first message multiplies your exposure to blocks.
***
## Adding Numbers Directly to Groups is a Spammy Action
Adding someone's number directly to a group **without their consent is treated by WhatsApp as a spam action in itself** — it's not just risky, it's one of the specific behaviors WhatsApp's enforcement measures. Users also have privacy settings that silently block group adds from strangers, so mass direct-adds both damage your score *and* fail to actually add many of the people.
**Why direct adds hurt you:**
1. **WhatsApp counts them.** Each direct add of a non-contact is a scored event. Dozens in a short window looks exactly like a spam operation building an audience.
2. **Recipients can report you from the group itself.** Every person added without consent is one tap away from "Report group" — and group-based reports are weighted heavily.
3. **Many adds silently fail.** Users with "Who can add me to groups" set to *My Contacts* can't be added by you at all; WhatsApp notes the attempt anyway.
4. **Added-without-consent members leave, mute, and report** at far higher rates, dragging down the group's own quality signals.
**Use invitation links instead:**
1. **No spam penalties:** WhatsApp flags mass direct additions but doesn't penalize invitation links; joining is voluntary.
2. **Better engagement:** Users who choose to join are more active and less likely to leave or report you.
3. **Looks organic:** Invitation-based growth mimics natural behavior and passes algorithm scrutiny.
**How to implement with Periskope:**
1. **Generate the link:** Create a group on WhatsApp and grab the invitation link (tap group settings → Group invite via link).
2. **Build the template:** In Periskope Bulk Messaging, create: "Hi %client\_name%, join our community for updates: \[your-group-link]"
3. **Send and monitor:** Use Periskope's message variables to personalize, send in batches (20–30 per day to avoid spam flags), and track who actually joins.
4. **Engage joiners:** Only follow up with people who accept the invite. They're pre-qualified and engaged.
If you must direct-add (e.g. an internal team group where everyone knows you), keep it to 15–20 additions per group per day, spaced out by 2–4 hours — and make sure the members already have your number saved.
***
## WhatsApp Restrictions: Time Locks and New-Chat Caps
Before banning a number outright, WhatsApp usually applies **graduated restrictions**. These are temporary, targeted penalties — and how you behave while restricted determines whether the number recovers or escalates toward a ban.
### Types of Restrictions
Your number is **temporarily blocked from initiating chats with new contacts**. Existing conversations usually keep working, but messages that would start a new chat are not delivered. Time locks come with an enforcement window — WhatsApp decides when it lifts, typically hours to days depending on severity and repeat offenses.
Instead of a hard lock, WhatsApp limits **how many new conversations you can start per cycle** (a rolling quota). You'll typically pass through warning stages first; if the behavior continues, the number becomes fully capped until the cycle resets.
Rate limits on group creation, group additions, or broadcast lists — often the first sign that your recent activity crossed a threshold.
### How You'll Notice — and How Periskope Shows It
1. Messages to **new contacts fail or silently don't deliver**, while existing chats work normally.
2. In Periskope, failed sends carry an **error indicator on the message** with the reason — a rejection caused by restrictions is called out explicitly.
3. Periskope monitors your number's restriction status directly from WhatsApp. When your phone is restricted you'll see a **warning in the New Chat window** (exactly where starting a new conversation would fail) and on the **phone connection screen**, including **when the restriction lifts** whenever WhatsApp provides an end time.
### What To Do When Restricted
Do not keep firing messages at new contacts "to test it." Every rejected attempt during a restriction reinforces the negative signal and can extend or escalate the penalty.
Replying to inbound messages and continuing existing chats is allowed and actively helps — it's exactly the "wanted communication" signal that rebuilds your score.
If Periskope shows an end time, plan around it. Restrictions lift automatically; there is no appeal path for a temporary time lock, and workarounds (like swapping SIMs into the same device patterns) make things worse.
Identify what triggered it — a purchased list? A burst of direct group adds? Volume spike? When the restriction lifts, resume at **half** your previous volume and rebuild gradually. A second restriction lands faster and lasts longer than the first.
If you maintain multiple warm numbers, shift *essential* new-contact messaging to a healthy number — at normal, careful volume. Do not dump the restricted number's entire queue onto it.
Repeated restrictions are WhatsApp telling you your current playbook doesn't work. Treat the second restriction as a final warning: numbers that cycle through multiple time locks are strong candidates for permanent bans.
***
## **Quick Risk Assessment**
Check where you stand:
| **Risk Factor** | **LOW** | **MEDIUM** | **HIGH** |
| :- | :- | :- | :- |
| Account Age | 3+ months | 2-4 weeks | New |
| Daily Messages | 5-20 | 20-50 | 100+ |
| New Chats Per Day | 0-10 | 10-30 | 50+ |
| User Consent | 100% | Partial | None |
| Spam Reports | 0 | 1-2 | 3+ |
| Group Adds | Invite links | Few direct adds | Mass direct adds |
***
## What to Do When Your WhatsApp Account is Banned
If your WhatsApp account is banned, it can be a challenging setback, especially if it impacts your business operations. However, in many cases, you can appeal to have your account reinstated. Follow the steps below to request an unblock and take measures to reduce the risk of future bans.
Open the WhatsApp app on your phone. If you see the message "Your phone number is banned from using WhatsApp. Contact support for help," tap on Contact Support.
* Describe your situation politely in the support form
* Avoid mentioning mass messaging or third-party automation tools
* Highlight consent and legitimate usage
* Include evidence of user consent to receive your messages, if applicable
* Note if users opted in to be contacted by you at an event
**Sample Appeal Message**
```text theme={null}
Hello,
I think my number may have been banned by mistake. I use it to stay in touch with
customers who shared their contact details with us and asked to hear from us.
Could you please review the ban? I'm happy to provide any additional information.
Thank you,
[Your Name]
```
Submit the form and wait for WhatsApp's response. This process typically takes \~24 hours.
***
## When Your Account is Unbanned: Prevent Future Bans
**Look at the timeline:** What messages were you sending? How many groups did you add? What was your daily message volume?
**Identify the trigger:** Was it rapid group creation? Mass messaging? Adding too many contacts at once? High-risk keywords or repeated patterns?
**Document the lesson:** Write down exactly what caused it so you never repeat those mistakes.
**Cap group creation:** Max 2 groups every 3 days (even slower than before).
**Limit contact additions:** 10–15 per group per day, not 20–30.
**Space out messaging:** Minimum 4–6 hour gaps between group sends. Randomize timing.
**Monitor daily caps:** Set a max of 50 messages per day for the first month, then slowly increase by 10–20 per week.
**Watch for warnings:** Delivery failures, read receipt drops, or messages not sending = red flag.
**Check account limits:** If you hit group creation or messaging restrictions mid-day, you're being rate-limited. Back off immediately.
**Track metrics:** Log daily sends, group adds, and delivery rates. Look for declining trends before a ban hits.
***
## When Reconnecting Your Number
* **Limit to phone-only for 5–7 days:** Don't touch WhatsApp Web, desktop, or any API integrations. Your number needs to appear like a normal personal phone user first.
* **Engage with real contacts:** Focus on conversations where people reply back. One-sided messaging (broadcasting to groups, sending unsolicited messages) is a red flag immediately after a ban.
* **Keep it conversational:** Short back-and-forth chats, not bulk sends. The algorithm is watching for natural behavior patterns.
* **Daily cap:** Stay under 30 messages per day during this period. Quality over quantity.
* **Start after day 7–10:** Wait until your phone-only behavior looks stable before adding Web access. Mix phone and Web usage; don't go 100% Web.
* **Maintain two-way conversations:** Don't use Web just to broadcast. Continue replying to messages and engaging with people who reach out.
* **Randomize access patterns:** Use phone for 2–3 days, then Web for 1–2 days. Avoid staying on Web 24/7; that looks automated.
* **Watch for warnings:** If you see delivery delays, failed messages, or read receipt drops on Web, go back to phone-only for another week.
* **Start micro:** First automation task: add 5 contacts to one group (max). Wait 24 hours. If no warnings, gradually scale.
* **Reimplement best practices:** Use the safeguards from earlier; space out group creation by 2–4 hours, add 10–15 contacts per group per day, keep messaging volume gradual.
* **Review what caused the ban:** Was it group creation speed? Messaging patterns? Keywords? Don't repeat those exact actions. If you were adding 100 contacts per day, cut that in half permanently.
* **Monitor obsessively:** Track every group creation, every message sent, delivery rates, read receipts. The moment something looks off, pause and investigate.
Following these steps helps safeguard your account and ensures your WhatsApp outreach remains compliant and effective. Remember that a banned account can severely impact your business operations.
***
## Warm Up a New Number
To ensure your new WhatsApp number gains trust and avoids restrictions, it's important to follow a gradual warm-up process. Start with light, natural activity and increase usage over time to help your number appear authentic and reliable.
For a full step-by-step guide, visit our [Warming Up Numbers guide](https://docs.periskope.app/get-started/warmup-numbers/) to learn the best practices for safe and effective account growth.
# Connect WhatsApp to Periskope
Source: https://docs.periskope.app/get-started/connect-whatsapp
Guide to connecting your WhatsApp numbers to Periskope
## Overview
You can connect Periskope to any normal or business WhatsApp number that you use for your official business communication.
**WhatsApp API numbers** cannot be linked to Periskope.
Once connected, Periskope will sync all chats and groups that this number is part of. You can then manage these chats and groups from the Periskope dashboard.
In order to perform any bulk actions like adding or removing members from a group, the connected WhatsApp number must be an admin on that group.
## Connecting WhatsApp to Periskope account
1. A phone number that you will use to manage all your official WhatsApp chats, groups and communities logged in on WhatsApp.
2. A Periskope account. If you don't have one, you can [sign up here](https://periskope.app/login).
Once logged into Periskope, you will see a Getting started screen with a `Scan QR` option as shown below.
1. Open Settings on your WhatsApp App and click on **Link device**
2. Now scan the QR code on the screem
If you face any errors, click on **refetch QR** to fetch a new QR code.
Once you're successfully connected to WhatsApp, you will see following screen on Periskope.
After the sync is performed, you'll be able to see the metrics and chats on Periskope.
To perform any action regarding your phone (such as restart, resync, delete), you can visit [here](https://periskope.app/settings/phones).
To add more phones, you can visit [here](https://periskope.app/settings/phones).
# Introduction
Source: https://docs.periskope.app/get-started/introduction
Your guide to get up and running with Periskope WhatsApp platform
## Overview
Are your struggling to manage a large number of official WhatsApp groups, chats and communities across multiple numbers? **Periskope is for you.**
Now seamlessly connect multiple WhatsApp numbers to a single inbox, organise your chats, schedule and send bulk messagas, create tasks and tickets and connect WhatsApp with your internal systems.
## Setting up
Download the Periskope app based on your operating system:
Download Periskope for Windows
Download Periskope for MacOS
Download Periskope for Android
Download Periskope for iOS
Learn how to setup your organization and connect WhatsApp to Periskope
Creating your organization and setting up your number
Guide to linking your WhatsApp to Periskope
## Demo Videos
Watch the Periskope demo video here:
## Guides
Tutorials and walkthroughs for all of Periskope's powerful features
Manage WhatsApp groups and chats across multiple numbers
Give access to multiple users to view & respond to WhatsApp messages
Intuitively organize chats, contacts and tickets with custom labels
Manage requests and tickets directly on WhatsApp groups
Insights on response rates, response times, open tickets and more
Export group data including members, contact details and roles
Convert queries into tickets directly on WhatsApp groups & chats
Create a task on WhatsApp and assign to your team
Schedule bulk messages to multiple groups with custom text, video, images
Setup scheduled and recurring messages on WhatsApp groups or chats
Automatically flag important messages with Periskope AI
Use Periskope AI to summarise chats and craft contextual responses
Automate chat actions liek replies, ticketing and escalations with powerful rules
Connect WhatsApp groups with Hubspot, Google Sheets, Salesforce Freshdesk and more
# Setting up your account
Source: https://docs.periskope.app/get-started/setup-account
Guide to setting up your organization account on Periskope
## Overview
To get started with Periskope, you need to create an account for your organization. As the creator of the organization, you will automatically be an admin. You can invite other members of your team later and assign roles
## Steps to setup
Go to the Periskope login page and login with your email. Periskope supports gmail and google workspace logins via SSO.
If you use any other email provider, please enter your email in the field provided. You will receive an OTP on your email from Periskope. Please check your spam folder in case you haven’t received it.
Once you’ve logged in, you will need to enter your organization name and your WhatsApp number. Please note that this is just a number we will use to connect with you and is not linked to the WhatsApp accounts you wish to manage on Periskope.
That's it! You can now connect all your WhatsApp numbers to Periskope and start managing your official groups and chats. Click here to learn how to [connect WhatsApp to Periskope](/get-started/connect-whatsapp)
# Warming Up New Numbers
Source: https://docs.periskope.app/get-started/warmup-numbers
A guide on warming up new numbers to improve the behavior scores and avoid bans
As WhatsApp continues to tighten its anti-spam measures, new phone numbers (especially those linked via eSIM) face a high risk of being flagged or blocked.
To minimize these risks, it’s important to gradually warm up new numbers by simulating organic usage patterns, which helps establish trust and reduce the likelihood of account restrictions.
This guide provides some essential best practices for warming up your number.
## What Is Number Warming?
Number warming is the gradual process of introducing a new phone number to messaging activity in a way that mimics natural user behavior. This helps establish trust with platforms like WhatsApp, reducing the risk of temporary bans or permanent blocks—especially important when using new numbers
## Steps to Warming Up Numbers
Successfully warming up a number typically takes 3 to 10 days. The goal is to simulate natural human behavior, not automated blasts. Here's how to do it right:
> ⚠️ Once the number is connected, avoid immediately sending messages. Let it breathe and ramp up gradually.
### 1. Initial Setup Phase
* Hold off on linking your freshly registered WhatsApp number to any other devices for a few days.
* If possible, consider using a dedicated proxy located in the same country (or even better, the same city) as your actual device. This helps maintain consistency in your number’s digital footprint.
* Next, complete your WhatsApp profile directly on your phone. Add a name, profile photo, and any other relevant details.
* Make sure your contact list isn’t empty. Aim to have 20–50 saved contacts. If that’s not possible, add a few manually.
* Finally, send a couple of genuine, handwritten messages to contacts you already know and try to get replies. Early back-and-forth conversation builds your behavior scores
### 2. Light Touch Engagement
* Start a few private chats (3–6) directly from your phone with contacts you already know. Keep it natural and casual.
* Send a few different types of messages. Avoid repetition and space them out.
* Include some media in your conversations, like images, videos, or stickers, to reflect typical WhatsApp behavior.
* Aim for replies. Getting responses to your messages helps establish normal engagement patterns.
### 3. Gradual Activity Increase
* Start initiating more new conversations each day. Slowly scale up the volume to mimic organic growth.
* Join and participate in group chats if available. Light, natural engagement is enough to show broader activity.
* Send a greater variety of messages, including longer texts, links, and different content types to diversify behavior.
* Make sure to respond to incoming messages. Sustained two-way communication signals healthy, human-like behavior.
### 4. Consistent Human-like Usage
* Create new groups or join existing ones, and engage actively with members to simulate genuine participation.
* Start using additional WhatsApp features—post status updates, follow or use channels, and try creating a community.
* Keep increasing your daily message volume and continue varying the content—mix text, media, links, and emojis for a well-rounded activity profile.
### 5. Ready for Real Work
If no issues have come up, the number can now begin connecting your phone to other sessions and start your normal activity
## Warming Up Tips
Here are some practical pointers to help your number blend in naturally and avoid getting flagged:
* 🧠 **Think like a human, not a bot.** Keep your activity random and organic. Avoid predictable or repetitive patterns.
* 📇 **Save before you send.** Always add the recipient to your contacts before initiating a conversation
* 🚫 **Don't go overboard.** Too many messages too fast or only sending messages without getting replies can trigger warnings.
* 🕐 **Spread activity across the day.** Avoid message bursts at fixed hours; instead, pace interactions like a typical user would.
* 📈 **Increase gradually.** Start small, then slowly scale up both the volume and variety of messages (text, emoji, media, etc.).
* 📘 **Brush up on the basics.** Don’t skip our guide on [Best Practices](https://docs.periskope.app/get-started/best-practices)
**Bonus tips:**
* 🔁 **Get replies.** WhatsApp favors two-way conversations, so aim to get responses, not just deliver messages.
* 🧪 **Test before scaling.** Try small volumes across a few numbers to see what works best before applying it at scale.
# Components of Automation Rules
Source: https://docs.periskope.app/integrations/automation-rules/components
## Components
Automation rules consist of three main components:
> #### Triggers
Triggers are events or notifications generated by the system or users that initiate the execution of a rule. They act as the starting point of an automation workflow.
> #### Conditions
Conditions that must be met for the actions to be executed, they allow for logical combinations of conditions using AND/OR operations and can include nested conditions up to a depth of 2.
> #### Actions
Actions are the tasks executed when the criteria are satisfied. Each action can be delayed, allowing it to be executed at a specific time.
# What are Automation Rules?
Source: https://docs.periskope.app/integrations/automation-rules/overview
Automation rules is a powerful feature in Periskope that allow you to automate your monitoring and alerting workflows. You can create rules that trigger actions based on specific conditions.
## What are automation rules?
Automation rules are a set of predefined conditions and actions that allow users to automate repetitive tasks within their system. These rules are designed to streamline processes, improve efficiency, and reduce manual intervention. By combining triggers, conditions, and actions, automation rules can execute complex workflows seamlessly.
## Why use automation rules?
1. **Efficiency**: Automation rules eliminate manual effort for repetitive tasks, saving time and resources.
2. **Accuracy**: Reduce human error by automating decisions and actions based on predefined criteria.
3. **Scalability**: Handle increasing workloads without adding additional manual processes.
4. **Customization**: Tailor workflows to specific needs using flexible triggers, conditions, and actions.
5. **Real-Time Response**: React to events as they occur, ensuring timely actions.
Automation rules are particularly useful in environments where large volumes of events, messages, or interactions need to be managed effectively, such as customer support, messaging platforms, and ticketing systems.
## How do automation rules work?
Automation rules operate through a structured workflow involving triggers, criteria, and actions:
**Trigger Initiation**: A predefined event (trigger) occurs, such as receiving a new message or updating a ticket. This event signals the system to evaluate the automation rule.
**Criteria Evaluation**: Once triggered, the system checks the specified conditions. These conditions can include logical combinations and delays, allowing for nuanced decision-making. If the criteria are met, the workflow proceeds to the next step.
**Action Execution**: Upon meeting the criteria, the specified actions are executed. Actions can be immediate or delayed based on the configuration.
For example, when a new message is flagged (trigger), the system evaluates whether it contains specific keywords (criteria). If the criteria are satisfied, the system sends an acknowledgment message to the user (action). This sequence ensures a seamless and automated process.
# Setting up Automation Rules
Source: https://docs.periskope.app/integrations/automation-rules/setup
Guide to set up automation rules in Periskope
## Components
Automation rules consist of three main components that need to be set up:
1. Triggers
2. Conditions
3. Actions
## Setting up Automation Rules
1. Go to the Automation Rules page in Periskope.
2. Click on the "+ New Rule" button. You can also add a rule by pre-filled templates available on the screen.
A total of 18 different preset templates that can be set up in just a few minutes, divided into 6 buckets:
1. Automated Ticketing
2. Automated Replies
3. Automated Assignments
4. Automated Flagging
5. Automated Escalation
6. Automated Notifications
On the top of the rule setup page, add a name for the rule.
In the "Trigger" section, select the event from the window that will initiate the rule. For example, "New Message Received."
Define the conditions that must be met for the rule to execute. You can add multiple conditions using logical operators like AND, OR, and nested conditions.
You can also add `delays` before evaluating the conditions to allow for time-based criteria.
For example, you can create a condition that checks if the message contains specific keywords and is received from a specific user.
Specify the actions that will be executed when the conditions are met. You can add multiple actions and set delays for each action.
Save the rule and publish it to start automating the workflow.
## Example: Automated replies on message with keywords (urgent, important) 📃
Let's consider an example of setting up an automation rule:
**Scenario**: Automatically send a message if a new message is received and contains certain keywords.
1. Select "New Message Received" as the trigger.
Define a condition: Check if the message contains specific keywords, e.g., urgent, help.
Use logical operators if needed: For example, message contains 'urgent' OR 'important'.
Optionally, set a delay before checking the condition (e.g., 5 minutes).
Select the action: 'Send Message' Action.
Specify the message to send, such as: "We have received your message and are processing your request."
Optionally, add a delay for when the action should be executed; and even some form of media (Image, Video, Document or Audio)
Save the rule and activate it to start automating the workflow.
### Final Rule:
* **Trigger**: When `New Message Received`
* **Conditions**: If message contains `urgent` OR `important`
* **Action**: Then send a message "We have received your message and are processing your request."
# Freshdesk
Source: https://docs.periskope.app/integrations/freshdesk
Guide to setup Freshdesk Integration on Periskope
## Prerequisites 📜
* A [Freshdesk](https://www.freshworks.com/freshdesk/) account
* A [Periskope account](https://console.periskope.app)
## Steps to connect Periskope with Freshdesk 🔧
1. To connect your Freshdesk, you must have a Periskope account. Once logged into the account, visit [here](https://console.periskope.app/settings/freshdesk) to connect Freshdesk.
2. Click on **connect**
In order to connect your Freshdesk account, you need to provide the following details:
1. **Freshdesk Domain**: Enter your Freshdesk domain. For example, `https://example.freshdesk.com`.
2. **API Key**: To get the API key, log in to your Freshdesk account and navigate to `Profile Settings` > `Your API Key`.
Now you have successfully connected your Freshdesk account with Periskope. You can now use the integration to sync tickets on Periskope to Freshdesk.
## Done 🎉
You've now successfully integrated Freshdesk with Periskope. Now you can sync tickets on Periskope to Freshdesk.
For any queries, reach out to us [here](https://what.sapp.link/periskope)
# Google Sheets
Source: https://docs.periskope.app/integrations/google-sheets
Connect Whatsapp to Google Sheets
### Introduction
This guide explains how to connect your Periskope platform directly to Google Sheets, allowing you to automatically sync your WhatsApp data for real-time reporting and analysis.
***
### Overview
Periskope’s Google Sheets integration eliminates manual data entry by piping events—such as new chats, incoming messages, and ticket updates—directly into your spreadsheets. You can monitor sync status and manage multiple data streams from a single dashboard.\\
***
### Prerequisites
Before you begin, ensure you have:
* A Google Account.
* A Periskope Account.
* A Google Sheet created and ready for data.
***
### Step-by-Step Setup
Follow these steps to authorize your account and start syncing data.
#### Step 1: Authorize Google Access
* Navigate to **Settings** and open the **Integrations** panel.
* Select **Google Sheets** from the list and click **Connect**.
* You will be redirected to the Google sign-in page; select the Google account you want to use.
* **Review Permissions:** Periskope will request access to see, edit, create, and delete specific Google Drive files and spreadsheets. Click **Allow**.
#### Step 2: Link Your Spreadsheet
* Once connected, click the **Add New Sheet** button.
* **Copy and Paste URL:** Open your target Google Sheet, copy the URL from your browser, and paste it into the URL field in Periskope.
* **Validation:** Ensure the sheet belongs to the same Google account you authorized in Step 1.
#### Step 3: Select Events & Subscribe
* Select the specific WhatsApp events you want to track in this sheet:
* **New Chats:** Logs whenever a new conversation starts.
* **Incoming Messages:** Captures all incoming text and media.
* **Ticket Updates:** Tracks changes in support ticket status.
* **Reactions:** Logs emoji reactions to messages.\
\
**Events** Currently, we support the following events for Google Sheets integration.
1. 👥 chat.created [**🔗**](https://docs.periskope.app/api-reference/objects/the-chat-object)
2. 💬 message.created [**🔗**](https://docs.periskope.app/api-reference/objects/the-message-object)
3. 💬 message.updated [**🔗**](https://docs.periskope.app/api-reference/objects/the-message-object)
4. 💬 message.deleted [**🔗**](https://docs.periskope.app/api-reference/objects/the-message-object)
5. 💬 message.ack.updated [**🔗**](https://docs.periskope.app/api-reference/objects/the-message-object)
6. 💬 message.ticket.attached [**🔗**](https://docs.periskope.app/api-reference/objects/the-message-object)
7. 😀 reaction.created [**🔗**](https://docs.periskope.app/api-reference/objects/the-reaction-object)
8. 😀 reaction.updated [**🔗**](https://docs.periskope.app/api-reference/objects/the-reaction-object)
9. 🏷️ ticket.created [**🔗**](https://docs.periskope.app/api-reference/objects/the-ticket-object)
10. 🏷️ ticket.updated [**🔗**](https://docs.periskope.app/api-reference/objects/the-ticket-object)
11. 🏷️ ticket.deleted [**🔗**](https://docs.periskope.app/api-reference/objects/the-ticket-object)
* Click **Subscribe** to finalize the connection.\\
***
## Troubleshooting
If you're not receiving data:
Verify that your Google Sheets connection is active in Periskope
Ensure you've granted all necessary permissions to Periskope
Confirm your Google account has sufficient access rights. Make your sheet access public to avoid any further issues.
If issues persist, reach out to our support team
### Revoking access manually for a fresh connection
If you're not receiving any data, your token might have been revoked from Google and will require you to do a fresh integration.
This should properly reset all your connection with Periskope. You can now reconnect your Google Sheet account with Periskope.
## Security and Permissions
Periskope maintains secure access to your Google Sheets through OAuth 2.0. You can review and revoke access at any time through your Google Account settings. Periskope only asks for limited permissions to your Google Sheet and Google Drive:
1. Read, Edit, Create and Delete only specific files on Google Drive that were shared with Periskope (via the URL)
2. See, Edit, Create and Delete your spreadsheets. (Only those via shared via the URL)
***
That's it! Your Periskope account is now connected to Google Sheets, and your selected data will automatically sync to your spreadsheets.See, Edit, Create and Delete your spreadsheets. (Only those via shared via the URL)
# HubSpot
Source: https://docs.periskope.app/integrations/hubspot
Guide to connect your HubSpot account with Periskope
> Periskope integration for HubSpot is currently under review. In order to use Periskope integration with HubSpot, you can connect with HubSpot from [Periskope HubSpot settings](https://console.periskope.app/settings/integrations/hubspot)
***
## Prerequisites 📜
* A [HubSpot](https://hubspot.com/) account
* A [Periskope account](https://console.periskope.app)
## Steps to connect Periskope with HubSpot 🔧
1. To connect your HubSpot, you must have a Periskope account. Once logged into the account, visit [here](https://console.periskope.app/settings/integrations/hubspot) to connect HubSpot.
2. Click on **connect**
In order to use Periskope workflow automations on HubSpot, check the workflow checkbox in HubSpot Connect Modal
Once you click on connect, you will be redirected to HubSpot connect page. Click on **Connect App** to connect your HubSpot account with Periskope.
Now you have successfully connected your HubSpot account with Periskope. You can now use the integration to link chats on Periskope with contacts/companies on HubSpot. And, also sync tickets on Periskope to HubSpot.
## What can be done with the integration ? 📃
You can perform multiple actions between Periskope and HubSpot. Here are some of the actions that can be performed with the integration.
### 1. Linking chats to HubSpot 🔗
1. You can **link chats** on Periskope to contacts/companies on HubSpot. This will help you to track the contact/company details of the user you are chatting with on Periskope.
->
->
You can also link chats to contacts/companies from the HubSpot.
2. Now you can **view** all details of the **linked contact/company** on the chat sidepanel on Periskope.
3. All the properties are **automatically synced** from HubSpot. But, you can also **refresh** or **unlink** the HubSpot properties manually from the chat sidepanel.
### 2. Syncing WhatsApp messages to HubSpot 💬
Once you have turned on [**Enable automatic WhatsApp chat logging for Contacts and Companies**](https://console.periskope.app/settings/integrations/hubspot) in HubSpot settings, all the WhatsApp messages will be logged to HubSpot for the linked contact/company.
Only new messages will be logged to HubSpot from when the integration option is turned on. The historical messages will not be logged to HubSpot.
You can view the WhatsApp messages logged to HubSpot on the contact/company page.
### 3. Syncing tickets to HubSpot 🎟️
1. Once you have linked your HubSpot account with Periskope. The tickets created on Periskope will be **automatically synced** to HubSpot.
2. You can choose to switch between `pipelines` on HubSpot to view the ticket in the respective pipeline.
If any new pipeline is created on HubSpot, you can **resync** the properties to view the new pipeline on Periskope.
Ticket created on Periskope is synced to HubSpot.
3. You can also **view details** of the **linked ticket** on the sidepanel of both the platforms.
Syncing of the details of already linked tickets between Periskope and HubSpot is `bi-directional`. But, you can only create tickets on Periskope and sync them to HubSpot.
4. You can also sync the **Ticket custom properties** of Periskope to HubSpot.
Create the ticket custom properties on Periskope and [**re-sync**](https://console.periskope.app/settings/integrations/hubspot) them to HubSpot.
The custom properties will be synced only in **uni-directional** manner. You can't sync the custom properties from HubSpot to Periskope.
5. Attached Message to a ticket
You can view the attached messages to a ticket on HubSpot.
### 4. Auto-create contacts and companies on HubSpot 👤
Once you have turned on [**Enable automatic contact/company creation**](https://console.periskope.app/settings/integrations/hubspot) in HubSpot settings, whenever a new chat is created on Periskope, a new contact/company will be created on HubSpot.
### 5. Sending a message using HubSpot workflow actions 📩
You can send a message to chats on Periskope using HubSpot workflow actions.
1. Click on **Create workflow** to create a new workflow.
2. Select the **Type of workflow** you want to create. You can choose from the following options: `Contact-based`, `Company-based`, `Ticket-based`
Click on **Set up triggers** and add a trigger event.
1. Click on **+** button to add an action.
2. Click on **Periskope** under Connected apps on the LHS sidepanel and choose `Send a message` action.
In order to send message to one or multiple Chat IDs, you need to fill the form with the following details:
#### Form fields -
Supports the Chat Id(s) to which you want to send the message. You can enter multiple Chat Ids separated by semi-colon.
Properties supported for this field are -
1. **Contact Properties** > `Periskope Chat IDs`
2. **Company Properties** > `Periskope Chat IDs`
3. **Ticket Properties** > `Periskope Chat ID`
Chat ID example -
1. Group Chat - `12036329726967XXXX@g.us`
2. Individual Chat - `9190043XXXXX@c.us`
Enter the message you want to send to the selected Chat ID(s).
Choose the sender phone number from the dropdown. The message will be sent from this organization number if active on Periskope at the time of trigger.
Send message action supports sending attachments to the Chat IDs.
You can add the public hosted URL of the media file you want to send as an attachment. You'll also need to specify type of media being sent.
Choose the media type from the dropdown.
Supported values are - `image`, `video`, `document`, `audio`.
Now you've successfully created a workflow on HubSpot to send a message to chats on Periskope. You can now test the workflow and publish it to send messages to chats on Periskope.
## Done 🎉
You've now successfully integrated HubSpot with Periskope.
For any queries, reach out to us [here](https://what.sapp.link/periskope)
## FAQs ❓
### 1. How to view Periskope properties on HubSpot?
Initially, you won't be able to view Periskope properties on HubSpot. But, once you link a chat to a contact/company on HubSpot, the properties will be synced to HubSpot.
To view properties on HubSpot, you can customize properties on the contact/company/tickets page to change the visibility.
You can choose the properties you want to view on the contact/company/tickets page.
### 2. Resyncing Periskope properties on HubSpot
In case you add new team members or new properties on Periskope, you can refresh the properties on HubSpot. To resync the properties, you can click on the **Resync properties** button in settings.
### 3. Updating scope of the integration
In case you want to add any available scope of the integration after connecting,
1. You can visit the [Periskope settings page](https://console.periskope.app/settings/integrations/hubspot) and click on **Delete**.
2. Choose to delete without removing data.
3. Reconnect the integrationg with added scope.
Currently we support only `workflows` as an additional scope.
### 4. Deleting the integration
To delete the integration, you can visit the [Periskope settings page](https://console.periskope.app/settings/integrations/hubspot) and click on **Delete**. You can choose to delete with or without data.
# Actions
Source: https://docs.periskope.app/integrations/workflows/actions
### Overview ℹ️
Actions are the tasks executed when the criteria are satisfied. Each action can be delayed, allowing it to be executed at a specific time.
Available Actions:
1. **Send Message** - Send a message to a chat or group.
2. **Forward Message** - Forward a message to another chat.
3. **Flag Message** - Flag a message in Periskope.
4. **Unflag Message** - Unflag a message in Periskope.
5. **Delete Message** - Delete a message from a chat.
6. **Create Ticket** - Create a new ticket in Periskope.
7. **Assign Ticket** - Assign a ticket to a user.
8. **Close Ticket** - Close a ticket in Periskope.
9. **Add Ticket Label** - Add one or more labels to a ticket.
10. **Add Chat Label** - Add one or more labels to a chat.
11. **Assign Chat** - Assign a chat to a user.
12. **Send Email** - Send an email to a user.
The available actions may vary based on the triggers selected. Not all actions are available for all triggers.
You can add multiple actions to a rule and set delays for each action.
### 1. Send Message To Chat 📩
The **Send Message** action allows you to send a message to a chat or group. You can customize the message content and choose the chat or group to send the message to.
**Action Inputs**
The chat or group to send the message to. You can search for the chat from the dropdown.
If you want to send the message to the same chat in which the workflow is triggered, you can select trigger chat from the dropdown.
The message content to be sent. You can add variables to personalize the message.
Example: `Hello {{ chat.chat_name || '' }}, your request has been received.`
Optional media file to attach to the message. You can upload an image, video, document, or other supported file type.
Whether to enable a cooldown period after sending the message. You can set a
cooldown period to prevent sending multiple messages in quick succession.
The duration of the cooldown period. You can specify the period in seconds,
minutes, hours, or days.
Option to maintain the flag status of the previous messages after sending the
message.
You can add variables to the message content to personalize the message.
Variables are placeholders that are replaced with actual values when the
message is sent and if the variable is not available, the fallback value is
used. Use variables to include dynamic information in the message, such as the
chat name, sender name, or ticket ID.
### 2. Forward Message 📩⏩
The **Forward Message** action allows you to forward a message to another chat.
**Action Inputs**
The chat or group to forward the message to.
### 3. Flag Message 🚩
The **Flag Message** action allows you to flag or unflag a message in Periskope.
### 4. Unflag Message 🚩
The **Unflag Message** action allows you to unflag a message in Periskope.
### 5. Delete Message 🗑️
The **Delete Message** action allows you to delete a message from a chat.
This action is irreversible. Once a message is deleted, it cannot be recovered.
You can only delete messages if you have the necessary permissions.
### 6. Create Ticket 🎫
The **Create Ticket** action allows you to create a new ticket in Periskope.
**Action Inputs**
The priority of the ticket. You can choose from No Priority, Low, Medium, High, or
Urgent. Only applicable when creating a new ticket.
The labels to add to the ticket. You can add multiple labels by selecting from
the dropdown. Only applicable when creating a new ticket.
The user to assign the ticket to. You can select the user from the dropdown. Only applicable when creating a new ticket.
You can assign ticket to user from a list on round-robin basis as well.
### 7. Assign Ticket 🎫👤
The **Assign Ticket** action allows you to assign a ticket to a user.
**Action Inputs**
Whether to assign the ticket using the round-robin method. You can enable
round-robin assignment to distribute tickets evenly among users.
The user(s) to assign the ticket to. You can select multiple users by selecting from the dropdown.
If round-robin assignment is enabled, you can select multiple users to assign tickets to.
### 8. Close Ticket ❌
The **Close Ticket** action allows you to close a ticket in Periskope.
**Action Inputs**
The note to add when closing the ticket.
### 9. Add Ticket Label Action 🎫🏷️
The **Add Ticket Label** action allows you to add one or multiple label to a ticket.
**Action Inputs**
The labels to add to the ticket. You can add multiple labels by selecting from
the dropdown.
### 10. Add Chat Label Action 💬🏷️
The **Add Chat Label** action allows you to add a label to a chat.
**Action Inputs**
The labels to add to the chat. You can add multiple labels by selecting from
the dropdown.
### 11. Assign Chat Action 💬👤
The **Assign Chat** action allows you to assign a chat to a user.
**Action Inputs**
Whether to assign the chat using the round-robin method. You can enable
round-robin assignment to distribute chats evenly among users.
Round-robin assignment assigns chats to users in a circular order. Each user
receives a chat in turn, ensuring an even distribution of chats among users.
The user to assign the chat to. If round-robin assignment is enabled, you can
select multiple users to assign chats to.
### 12. Send Email Action 📧
The **Send Email** action allows you to send an email notification to any email address.
**Action Inputs**
The email address to send the email to.
The subject of the email. You can add variables to personalize the subject.
Example: `New ticket created: {{ ticket.ticket_id || '' }}`
You can add variables to the subject to personalize the email. Variables
are placeholders that are replaced with actual values when the email is sent
and if the variable is not available, the fallback value is used. Use
variables to include dynamic information in the subject, such as the ticket ID
or chat name.
The email content to be sent. You can add variables to personalize the email.
Example: `Hello, new ticket {{ ticket.ticket_id || '' }} has been assigned to you.`
You can add variables to the email body to personalize the email. Variables
are placeholders that are replaced with actual values when the email is sent
and if the variable is not available, the fallback value is used. Use
variables to include dynamic information in the email, such as the ticket ID,
chat name, or sender name.
# Overview
Source: https://docs.periskope.app/integrations/workflows/overview
Workflows are a powerful feature in Periskope that allow you to automate your monitoring and alerting workflows. You can create workflows that trigger actions based on specific conditions.
## What are workflows?
Workflows are a set of predefined actions that allow users to automate tasks within their system. These workflows are designed to streamline processes, improve efficiency, and reduce manual intervention. By combining triggers, conditions, and actions, workflows can execute complex workflows seamlessly.
Think of workflows as:
“If this happens → then do a set of things automatically, if not then do other set of things automatically.”
#### Each workflow is made up of:
What starts the workflow
One or more steps that run automatically
## Why use workflows?
1. **Scalability**: Handle increasing workloads without adding additional manual processes.
2. **Customization**: Tailor workflows to specific needs using flexible triggers, conditions, and actions.
3. **Real-Time Response**: React to events as they occur, ensuring timely actions.
4. **First response time**: Improve first response time by automating responses to common queries.
Workflows allow you to automate responses, route chats, take actions, and enforce rules at scale.
## How do workflows work?
Workflows operate through a structured workflow involving triggers, conditions, and actions:
**Trigger Initiation**: A predefined event (trigger) occurs, such as receiving a new message or updating a ticket. This event signals the system to evaluate the automation rule.
**Action Execution**: Upon meeting the criteria, the specified actions are executed. Actions can be immediate or delayed based on the configuration.
For example,
when a new message is received (trigger), the system evaluates
whether it contains specific keywords (criteria). If the criteria are
satisfied, the system creates a new ticket (action). After sometime, the system again checks if the message is responded to (action), if so, the system closes the ticket (action) or else it escalates the ticket and forwards the message to a human agent chat(action).
This sequence ensures a seamless and automated process.
# Triggers
Source: https://docs.periskope.app/integrations/workflows/triggers
## Overview
Triggers are events or notifications generated by the system or users that initiate the execution of a workflow. They act as the starting point of an automation workflow.
Available Triggers:
When a new chat/ group is created.
The list of organization phone numbers that are allowed to trigger the
workflow.
When a label is added or removed from a chat.
The list of organization phone numbers that are allowed to trigger the
workflow.
When a reaction is added to a message.
The list of organization phone numbers that are allowed to trigger the
workflow.
When a new message is received in a chat from an external number or internal number (if enabled). You can choose to trigger the workflow when a new message is received from an
external number or internal number (if enabled).
The list of organization phone numbers that are allowed to trigger the workflow.
Allow messages from internal numbers to trigger the workflow.
When a message is edited/ updated.
The list of organization phone numbers that are allowed to trigger the workflow.
When a message is flagged by AI or manually by a user.
The list of organization phone numbers that are allowed to trigger the workflow.
When a message is unflagged by AI or manually by a user.
The list of organization phone numbers that are allowed to trigger the workflow.
When a message is deleted in a chat.
The list of organization phone numbers that are allowed to trigger the workflow.
When a new ticket is created on Periskope.
When a ticket property is updated. For e.g. subject, status, priority, due date etc.
When a label is added or removed to a ticket.
When a ticket is closed.
When a new task is created.
When a task is assigned to a user.
# Zapier
Source: https://docs.periskope.app/integrations/zapier
Guide to setup zapier triggers on Periskope
> Periskope integration for zapier is currently in private mode. In order to use periskope triggers in your zaps please [click here to obtain access](https://zapier.com/developer/public-invite/217966/ff590dfcc26be42cf2e51df10516d6a9/) to the private beta in zapier
***
## Prerequisites
* A [Zapier](https://zapier.com/) account
* Access to the Periskope app in Zapier [request here](https://zapier.com/developer/public-invite/217966/ff590dfcc26be42cf2e51df10516d6a9/)
* A [Periskope account](https://console.periskope.app)
## Setting up the Zapier integration on Periskope
To generate an API key for your zap, you must have a Periskope account.
Once logged into the account, visit [here](https://console.periskope.app/settings/integrations/zapier) to generate an API key. API key can only be revealed once, so please keep this API key safe and at a secure place.
Periskope zapier integration currently is in private mode. In order to get access click [here](https://zapier.com/developer/public-invite/217966/ff590dfcc26be42cf2e51df10516d6a9/)
## Steps to setup a trigger
Go to [zapier dashboard](https://zapier.com/app/dashboard). And click on `Create`
Once you've created a new zap. Click on Add trigger. Search for `periskope`
Currently we support following events.
1. [New ticket created](#new_ticket) - Triggers every time a new ticket is created on periskope
Create a new account and authenticate with API key generated on periskope
In order to initially pull a new records with all the fields that you'll be receiving from periskope. Click on test your trigger.
## Result 🚀
* Now your zap trigger is connected to your periskope account and you can add any action of your choice to stream the data from periskope to your application.
* Once the action has been setup you can test the step and publish your zap to subscribe to the trigger.
That's it! You have now added Zapier integration on Periskope. You can now trigger zap from periskope for chosen event.
# Events
Currently we support following events for zapier.
1. 👥 chat.created [🔗](/api-reference/objects/the-chat-object)
2. 💬 message.created [🔗](/api-reference/objects/the-message-object)
3. 💬 message.updated [🔗](/api-reference/objects/the-message-object)
4. 💬 message.deleted [🔗](/api-reference/objects/the-message-object)
5. 💬 message.ack.updated [🔗](/api-reference/objects/the-message-object)
6. 💬 message.ticket.attached [🔗](/api-reference/objects/the-message-object)
7. 😀 reaction.created [🔗](/api-reference/objects/the-reaction-object)
8. 🏷️ ticket.created [🔗](/api-reference/objects/the-ticket-info-object)
9. 🏷️ ticket.updated [🔗](/api-reference/objects/the-ticket-info-object)
10. 🏷️ ticket.deleted [🔗](/api-reference/objects/the-ticket-info-object)
# Zoho CRM
Source: https://docs.periskope.app/integrations/zohocrm
Guide to connect your Zoho CRM account with Periskope
> Periskope integration for Zoho CRM is currently under review. In order to use Periskope integration with Zoho CRM, you can connect with Zoho CRM from [Periskope Zoho CRM settings](https://console.periskope.app/settings/integrations/zohocrm)
***
## Prerequisites 📜
* A [Zoho CRM](https://www.zoho.com/crm/) account
* A [Periskope account](https://console.periskope.app)
## Steps to connect Periskope with Zoho CRM 🔧
1. To connect your Zoho CRM, you must have a Periskope account. Once logged into the account, visit [here](https://console.periskope.app/settings/integrations/zohocrm) to connect Zoho CRM.
2. Click on **connect**
**Important:** If you are using the free version of Zoho CRM without any active trials, make sure to check **"Skip automatic two-way sync"** in the connect modal. This is because the connection creates webhooks at the backend, and the free edition of Zoho CRM doesn't support webhooks.
Once you click on connect, you will be redirected to Zoho CRM connect page. Click on **Accept** to connect your Zoho CRM account with Periskope.
Now you have successfully connected your Zoho CRM account with Periskope. You can now use the integration to link chats on Periskope with contacts, accounts or leads on Zoho CRM.
## What can be done with the integration ? 📃
You can perform multiple actions between Periskope and Zoho CRM. Here are some of the actions that can be performed with the integration.
### 1. Linking chats to Zoho CRM 🔗
1. You can **link chats** on Periskope to contacts/accounts/leads on Zoho CRM. This will help you to track the contact/account details of the user you are chatting with on Periskope.
->
->
2. Now you can **view** all details of the **linked contact/account** on the chat sidepanel on Periskope.
3. All the properties are **automatically synced** from Zoho CRM. But, you can also **refresh** or **unlink** the Zoho CRM properties manually from the chat sidepanel.
### 2. Syncing WhatsApp messages to Zoho CRM 💬
Once you have turned on [**Enable automatic WhatsApp chat logging for Contacts, Accounts and Leads**](https://console.periskope.app/settings/integrations/zohocrm) in Zoho CRM settings, all the WhatsApp messages will be logged to Zoho CRM for the linked contact/account/lead.
Only new messages will be logged to Zoho CRM from when the integration option is turned on. The historical messages will not be logged to Zoho CRM.
You can view the WhatsApp messages logged to Zoho CRM on the contact/account/lead page.
### 4. Auto-create contacts and accounts on Zoho CRM 👤
Once you have turned on [**Enable automatic contact/account creation**](https://console.periskope.app/settings/integrations/zohocrm) in Zoho CRM settings, whenever a new chat is created on Periskope, a new contact/account will be created on Zoho CRM.
## Done 🎉
You've now successfully integrated Zoho CRM with Periskope.
For any queries, reach out to us [here](https://what.sapp.link/periskope)
## FAQs ❓
### 1. How to view Periskope properties on Zoho CRM?
When you do integration for the first time, the properties will be created on Zoho. Once you link a chat to a contact/account on Zoho CRM, the properties will be synced to Zoho CRM.
To view properties on Zoho CRM, you can customize properties on the contact/account/tickets page to change the visibility.
You can choose the properties you want to view on the contact/account/tickets page. The image below shows how we can add/remove properties from the contacts.
### 2. Resyncing Periskope properties on Zoho CRM
In case you add new team members or new properties on Periskope, you can refresh the properties on Zoho CRM. To resync the properties, you can click on the **Resync properties** button in settings.
### 3. Deleting the integration
To delete the integration, you can visit the [Periskope settings page](https://console.periskope.app/settings/integrations/zohocrm) and click on **Delete**. You can choose to delete with or without data.
# Zohodesk
Source: https://docs.periskope.app/integrations/zohodesk
Guide to setup Zohodesk Integration on Periskope
> Periskope integration for ZohoDesk is currently under review. In order to use Periskope integration with Zoho Desk, you can connect with Zohodesk from [Periskope Zohodesk settings](https://console.periskope.app/settings/integrations/zohodesk)
***
## Prerequisites 📜
* A [Zohodesk](https://www.zoho.com/desk) account
* A [Periskope account](https://console.periskope.app)
## Steps to connect Periskope with Zohodesk 🔧
1. To connect your Zohodesk, you must have a Periskope account. Once logged into the account, visit [here](https://console.periskope.app/settings/integrations/zohodesk) to connect Zohodesk.
2. Click on **connect**
Once you click on connect, you will be redirected to Zohodesk connect page. Click on **Connect App** to connect your Zohodesk account with Periskope.
Now you have successfully connected your Zohodesk account with Periskope. You can now use the integration to sync tickets on Periskope to Zohodesk.
## Done 🎉
You've now successfully integrated Zohodesk with Periskope.
For any queries, reach out to us [here](https://what.sapp.link/periskope)
## FAQs ❓
### 1. How to view Periskope properties on Zohodesk?
Initially, you won't be able to view Periskope properties on Zohodesk.
To view properties on Zohodesk, you can customize properties on the Layouts page to change the visibility.
You can choose the properties you want to view on the tickets page.
### 2. Deleting the integration
To delete the integration, you can visit the [Periskope settings page](https://console.periskope.app/settings/integrations/zohodesk) and click on **Delete**. You can choose to delete with or without data.
# Create Ticket with an Emoji
Source: https://docs.periskope.app/tasks-and-reminders/emoji-ticketing
Automatically create support tickets by reacting to WhatsApp messages with emoji. Fast, intuitive, and requires zero manual work.
## Overview
How often have you missed a customer message on WhatsApp, only to catch it too late? Good news, you don't have to manually create tickets anymore. With Periskope, you can simply react to a message, and a ticket will be created automatically. One emoji reaction. Instant ticket creation. Zero context lost.
## How It Works
The workflow is simple. Set up an automation rule that triggers when someone reacts to a message with a specific emoji (like thumbs up 👍). When that emoji is added, a new ticket is automatically created, or the message is attached to an existing ticket. Here's the complete flow:
* Team member sees an important WhatsApp message
* They react to it with your chosen emoji (e.g., 👍)
* Automation rule triggers immediately
* New ticket is created or message attached to existing ticket
* Ticket appears in dashboard ready for your team to work on
## Setting Up Your Emoji Ticketing Rule
> #### Step 1: Start a New Rule
Go to "Automation Rules" > Click "New Rule"> Select "Create from Scratch" to build a custom rule for your workflow.
> #### Step 2: Name Your Rule
Give your rule a clear name. Example: Create Ticket with Thumbs Up or Flag Messages with Heart.
> #### Step 3: Select Your Trigger
Set the trigger to "New Reaction Added". This activates your rule whenever anyone adds an emoji reaction to any message.
> #### Step 4: Define Your Condition - Choose the Emoji
Go to Criteria. Add condition and select "Reaction" as your condition and choose which emoji you want to monitor. A few choices include:
* Thumbs up (👍) - Most intuitive for approvals and important messages
* Heart (❤) - Great for favorite customers or priority issues
* Star (⭐) - Perfect for high-priority or critical bugs
* Fire (🔥) - For urgent or trending issues
* Flag (🚩) - For items that need attention
You can add multiple conditions, i.e. multiple emojis which would be considered by the rule.
> #### Step 5: Set Evaluation Timing
Adjust the Check Conditions After time. This controls how long after someone reacts the rule evaluates. Immediate or 5 seconds is usually best for quick ticket creation.
> #### Step 6: Choose Your Action
Go to Actions and select "Create ticket or attach message to latest ticket"
When triggered:
* If no existing ticket is found, a new ticket is created.
* If a ticket already exists, the message is attached to the latest ticket instead of creating a duplicate.
This helps prevent duplicate tickets while keeping related issues grouped together. You can also choose a specific assignee or distribute tickets automatically using a round-robin method.
> #### Step 7: Save and Publish
Review your rule. Click Save to store it. Click Publish to activate it. Your emoji ticketing rule is now live.
# Create a Task
Source: https://docs.periskope.app/tasks-and-reminders/tasks
Convert any WhatsApp message into a task with one click. Instantly create, assign, and manage tasks without leaving the chat.
## Overview
You are managing multiple WhatsApp conversations. Important messages come in every day, but they often get buried in chats. You either try to remember them, scroll back later, or manually copy them into another tool. This process is time-consuming and easy to miss, leading to forgotten tasks and missed follow-ups. Create tasks directly from WhatsApp messages with a single click with the help of Periskope. No switching tools. No manual copying. All message context is automatically included, tasks are assigned instantly, and your team stays aligned on what needs to be done.
## How It Works
Creating a task from a WhatsApp message is simple:
* Find the message you want to convert
* Right-click and select Create Task
* Fill in task details (name, assignee, priority, etc.)
* Click Save
* Task is created and linked to the message
The original message stays connected to the task, so you always have full context without needing to search again.
## Step-by-Step Guide:
Open the WhatsApp conversation and locate the message you want to convert into a task. This could be a request, reminder, or any action item that needs tracking.
Right-click (or long-press on mobile) on the message. A menu will appear. Select Create Task from the available options.
Enter a clear and descriptive name for your task. This helps everyone understand what needs to be done at a glance.
Choose a due date and estimate how much time is required to complete the task. This helps in planning and prioritization. You can set predetermined time/date or add your own custom dates.
Select the person responsible for completing the task. Assigning ownership ensures accountability and faster execution.
Choose between Low, Medium, or High priority depending on urgency. This helps your team focus on what matters most.
Set reminders so the assignee gets notified at the right time. This ensures tasks are not forgotten. You can set predetermined time/date or add your own custom dates.
Include any additional context or instructions that may help complete the task more effectively.
Review all details and click Save. The task is created and linked to the original message. Notifications are sent automatically.
## Create Tasks Without Messages
You can also create tasks from scratch using the Create Task button. Head to the top right of your Periskope dashboard, where you can find the tasks button. These tasks don’t need to be linked to a WhatsApp message. Use this for internal work, follow-ups, or starting new conversations.
## Managing Your Tasks
* **View All Tasks:** Go to the Tasks tab at the top right to see all your tasks. You can view your open tasks, all active tasks, tasks assigned to you, high priority tasks, and all tasks.
* **Track Progress:** Monitor active tasks and update them as work progresses.
* **Close Tasks:** Mark tasks as completed once they are done to keep your workspace clean and organized.
* **Filter tasks:** Filter out the tasks that aren't needed and only view those that are important. You can filter by due date, priority, assignee, or status to quickly find what you need.
# Create a Ticket on WhatsApp
Source: https://docs.periskope.app/tickets/create-ticket
Convert any WhatsApp message into a support ticket with one click. Instantly create, assign, and manage tickets without leaving the chat.
## The Challenge
You are managing dozens of WhatsApp conversations. A customer sends an urgent message that needs to become a support ticket. You manually copy the details, switch to your ticketing system, and create a ticket. Time-consuming and error prone. Solution: Create tickets directly from WhatsApp messages with a single click. All context preserved. All details pre-filled. Instant.
> ### How It Works
Creating a ticket from a WhatsApp message is simple:
* Find the message you want to convert into a ticket
* Right-click the message and select "Create Ticket "
* Fill in ticket details (title, priority, assignment, etc.)
* Click "Create Ticket"
The ticket is created and linked to the conversation, the original message content is automatically included in the ticket, and the ticket remains connected to the full conversation history.
## Getting Started: Find Message and Create Ticket
> #### Step 1: Find Your Message
Open the WhatsApp conversation in Periskope and locate the message you want to convert into a ticket. This could be a customer request, complaint, feature request, or any message that needs tracking.
> #### Step 2: Right-Click to Create Ticket
Right-click (or long-press on mobile) on the message. A context menu will appear. Select Create Ticket from the menu options.
The message text is automatically captured in the ticket. You dont need to copy anything manually.
> #### Step 3: Add a Ticket Title
Enter a clear, descriptive title for your ticket. This helps your team quickly understand the issue at a glance.
Examples:
* Billing inquiry - customer overcharged
* Feature request - export to CSV
* Account locked - reset password needed
* Payment processing issue - urgent
Avoid vague titles like "Help needed", "Question", or "Issue with account". Specific titles help your team work faster.
## Configure Ticket Details
> #### Step 4: Set Ticket Status
Choose the initial status for your ticket. Most new tickets start as Open. You can change the status later as your team works on it.
| Status | Meaning |
| - | - |
| Open | New ticket, waiting to be addressed |
| In Progress | Team member is actively working on it |
| Closed | Issue has been resolved |
> #### Step 5: Assign to a Team Member
Choose which team member should handle this ticket. Either assign to a specific person to ensure they see it immediately or leave unassigned for your team queue to pick up. This ensures the right person starts working on it right away.
> #### Step 6: Set Priority
Define how urgent the ticket is. Priority helps your team focus on what matters most: \_ \_
* Low - non-urgent, can be addressed when team has capacity
* Medium - Standard request, can be scheduled
* High - Important but not an emergency, should be handled soon
* Urgent - Needs immediate attention, customer is frustrated
> #### Step 7: Set Due Date
Define when the ticket should be resolved. Due dates help track SLA compliance. For example: Use 1 hour for urgent, 4 hours for high priority, 24 hours for Medium, 3-5 days for low priority.
> #### Step 8: Add Labels
Labels help organize and categorize tickets. Create labels for:
* channels (Support, Billing, Technical)
* urgency (Urgent, Follow-up)
* or types (Bug Report, Feature Request)
You can add multiple labels to a single ticket and use them later to filter and route tickets.
> #### Step 9: Add Custom Properties
Custom properties capture additional workflow-specific information like Team assignment, Product category, Customer tier, or Account status. Set these up in Settings > Custom Properties > Tickets, then use them to add context that helps your team understand the issue faster.
## Complete Your Ticket
> #### Step 10: Create the Ticket
Review all details one final time. Click Create Ticket to finalize. The ticket is now created and automatically linked to the original WhatsApp conversation. Your assigned team member receives a notification immediately and can start working on the issue.
# Track and Export Ticket Metrics
Source: https://docs.periskope.app/track-and-export-ticket-metrics
Monitor ticket resolution, workload, and team performance. Understand if your team is keeping up or falling behind with real-time visibility.
## Overview
Sometimes your ticket queue looks busy, but it's not always clear if your team is actually keeping up or starting to fall behind. With Periskope's Ticket Metrics Dashboard, you get a clear view of what's happening so you can understand performance at a glance. Stop guessing. Start measuring ticket efficiency.
## How It Works
The Ticket Metrics Dashboard gives you a complete view of your ticket system performance:
* Quick Snapshot - Key metrics at a glance
* Ticket History Graph - Trends over time
* Individual Performance - Team member breakdown
Together, these views help you understand ticket volume, resolution efficiency, and identify team members who might need support.
## Accessing the Ticket Metrics Dashboard
From your Periskope dashboard, go to Analytics > Ticket Metrics. You'll see your complete ticket performance overview with customizable filters and date ranges.
## Quick Snapshot - Key Metrics
The Quick Snapshot gives you an instant overview of your ticket system health. These are the core numbers that tell you if your team is keeping up.
1. **Tickets in Progress:** The number of tickets currently being actively worked on. This shows your team's current workload. High numbers might indicate your team is busy. Compare this to your team size to assess if workload is balanced.
2. **Unresolved Tickets:** Total tickets that are not yet closed (includes both Open and In Progress). This shows backlog. If this number is growing over time, your team might be falling behind.
3. **Resolved Tickets:** Number of tickets closed during your selected period. High numbers show productivity. Compare resolved vs unresolved to see if your team is catching up or accumulating backlog.
4. **Unassigned Tickets:** Tickets with no owner yet. These need attention. If this number is high, bottlenecks might be in assignment, not resolution. Assign these quickly to prevent delays.
5. **Average Resolution Time:** How long it typically takes your team to close a ticket. This is your efficiency metric. If it's increasing, investigate why tickets are taking longer. Set target resolution times and track against them.
## Customizing Your View with Date Ranges and Filters
1. **Date Range Selection:** Adjust the date range to focus on specific periods. Last 24 hours shows daily performance. Last 7 days shows weekly trends. Last 30 days shows monthly patterns. Custom ranges let you analyze specific projects or campaigns.
2. **Filter by Label:** Focus on specific ticket categories. Example: Filter for only Billing or Technical tickets. This helps you understand performance per category.
3. **Filter by Priority:** See how your team handles different urgency levels. Are Urgent tickets resolved faster? Are Low priority tickets piling up? This reveals capacity and priorities.
4. **Filter by Status:** Focus on Open, In Progress, or Closed tickets. Understand the split. If lots are Open and few are In Progress, assignment might be slow.
5. **Filter by Assignee:** See individual team member performance. Which agents are handling tickets? Who might be overloaded or underutilized?
6. **Filter by Urgency:** Monitor how critical issues are being handled. Are urgent tickets being prioritized? Track resolution speed for high-urgency items.
7. **Filter Logic \[All vs Any]:** When applying multiple filters, you can choose how they combine:
* ALL- Ticket must match EVERY filter. Example: Show tickets that are Urgent AND Billing AND assigned to Sarah. Narrows results significantly.
* ANY- Ticket can match ANY filter. Example: Show tickets that are Urgent OR Unassigned. Broader view of potential issues.
## Ticket History Graph - Visualizing Trends
The Ticket History graph shows ticket activity over your selected period. This visual view reveals patterns and trends instantly.
1. **Unresolved Tickets Line:** Shows open and in-progress tickets over time. If this line is trending upward, your team is accumulating backlog. If it's stable or declining, you are keeping pace.
2. **Tickets Created Line:** Shows incoming ticket volume. Spikes show busy periods. Compare this to the unresolved line. If unresolved grows while created stays flat, your team is slowing down.
3. **Tickets Closed Line:** Shows resolution rate. Higher numbers mean more tickets resolved. Compare to created. If created > closed, backlog is building.
## Individual Performance Breakdown
Scroll down to see how each team member is performing. This is where you identify who might need support or additional workload.
1. **Total Tickets Assigned:** How many tickets each agent has been given. Compare across team members. Big differences might indicate unbalanced assignment.
2. **Open or In Progress:** Current active workload for each agent. Who has the most tickets being worked on right now? If one person has significantly more, consider rebalancing.
3. **Tickets Closed:** Productivity metric. Who is closing the most tickets? This shows resolution rate, but don't confuse speed with quality. Fast doesn't always mean good.
4. **Average Resolution Time:** How long each agent typically takes to close a ticket. Compare across team. If one person is much slower, they might need support or training.
5. **Unresolved Count:** Tickets still pending for each agent and for how long they have remained unresolved. High numbers might indicate they need help, are blocked, or need additional resources.
# Fix "Blank screen or Out of memory issues"
Source: https://docs.periskope.app/troubleshooting/clear-cache
Guide to fix app crashes across different browsers
In this doc, we'll know how to clear cache and cookies for periskope on browsers to prevent uninterrupted access to app.
1. Open [Periskope](https://console.periskope.app).
2. In the address bar, beside URL. Click on sheild icon
1. Click on Reset all data
In this doc, we'll know how to clear cache and cookies for periskope on browsers to prevent uninterrupted access to app.
1. Open [Periskope](https://console.periskope.app).
2. In the address bar, beside URL. Click on settings icon
3. Cookies and site data > Manage on-device site data
1. Click on Reset all data
# Fix "Can't use Periskope due to App crashes"
Source: https://docs.periskope.app/troubleshooting/clear-memory
Guide to fix app crashes across different devices
Periskope app crashes usually occur due to memory allocated to the App.
In this doc, we provide instructions on how to clear data for Periskope on iOS browsers to prevent uninterrupted access to app.
## Clear Specific Website Data (periskope.app)
### Safari on iOS -
Remove individual sites by tapping the red minus icon.
Or scroll down and tap Remove All Website Data to clear all.
## Clear all website data
### Chrome on iOS -
For chrome, specific website data cannot be removed. So, we'll need to clear all browsing data in case of Periskope App crashes.
1. Open the Chrome app
2. Tap three-dot menu at bottom-right
3. Tap **Delete browsing data** from the list
Choose the following to clear website data for Periskope -
1. **Browsing History**
2. **Cookies, Site Data**
3. **Cached Images and Files**
4. Saved Passwords (optional)
5. Autofill Data (optional)
6. Tabs (optional)
1. Choose time range - All time
2. Tap **Delete data** and confirm
In this doc, we'll know how to clear data for periskope on browsers to prevent uninterrupted access to app.
## In-app Periskope cache clean
### Periskope (console.periskope.app) -
Clearing data from Periskope
1. Open Periskope.
2. In the top menu bar, click **Help❓** button
3. Click **App slow?** button
1. Click on Reset all data
## Clear Specific Website Data (periskope.app)
### Safari on macOS -
1. Open Safari.
2. In the top menu bar, click Safari > Settings (or Preferences depending on your macOS version).
3. Go to Privacy Tab
4. Click **Manage website data** button
1. Use the search bar to find the specific website (e.g., example.com).
2. Select the website from the list.
3. Click Remove (or Remove All if you want to clear all).
4. Click Done.
# Fix "Chats not loading"
Source: https://docs.periskope.app/troubleshooting/loading-chat
Guide to fix chats not loading issue on different browsers
In this doc, we'll know how to clear all data for periskope like cookies, localStorage, sessionStorage, and the browser database to resolve chats not loading issue.
1. Open [Periskope](https://console.periskope.app).
2. In the header, beside refresh button. Click on Help
1. Click on Clear all local data
After clearing your data, you will be logged out. Please fully close and restart your browser before logging in
In this doc, we'll know how to clear all data for periskope like cookies, localStorage, sessionStorage, and the browser database to resolve chats not loading issue.
1. Open [Periskope](https://console.periskope.app).
2. In the header, beside refresh button. Click on Help
1. Click on Clear all local data
After clearing your data, you will be logged out. Please fully close and restart your browser before logging in
# Fix "Not receiving notifications on Periskope"
Source: https://docs.periskope.app/troubleshooting/notifications
Guide to enable Periskope notifications on different devices
In order to enable Periskope notifications on iOS device, you'll need to follow these steps -
In this doc, we provide instructions on how to clear data for Periskope on iOS browsers to prevent uninterrupted access to app.
## Enable notifications on iOS
In iOS, notifications can only be enabled for the Periskope App PWA, not for other browser.
1. Go to your phone's **Settings** app
2. Tap **Notifications**
3. Find and tap on **Periskope**
4. Toggle the switch to enable notifications for Periskope
1. Go to your phone's **Settings** app
2. Tap **Safari** under **Apps**
3. Tap **Advanced**
4. Tap **Feature Flags**
5. Enable **Declarative Web Push** and **Notifications**
## Enable notifications for Periskope App
1. Delete Periskope bookmark from your home screen
1. Open the Safari app
2. Go to [Periskope](https://console.periskope.app)
3. Tap the **Share** button (the square with an arrow pointing up)
4. Select **Add to Home Screen**
5. Enable notifications when prompted
6. Also, enable notifications for Periskope from topbar
For older versions of iOS, you might need to enable notifications differently in Settings. Please refer the following image -
Make sure you reinstall the Periskope App PWA after enabling notifications in Settings.
In order to enable Periskope notifications on Android device, you'll need to follow these steps -
In this doc, we provide instructions on how to enable notifications for Periskope on Android devices.
## Enable notifications for Periskope App
For chrome, specific website data cannot be removed. So, we'll need to clear all browsing data in case of Periskope App crashes.
1. Open the Chrome app
2. Go to [Periskope](https://console.periskope.app)
3. Tap the three-dot menu at the top-right corner
4. Save the site as a shortcut on your home screen
5. Enable notifications when prompted
1. Go to your phone's **Settings** app
2. Tap **Apps & notifications**
3. Find and tap on **Chrome**
4. Tap **Notifications**
5. Toggle the switch to enable notifications for Chrome
In order to enable Periskope notifications on macOS device, you'll need to follow these steps -
In this doc, we provide instructions on how to enable notifications for Periskope on macOS browsers.
## Enable notifications for Periskope on macOS
1. Click on the **Apple menu** () in the top-left corner
2. Select **System Settings** (or **System Preferences** on older macOS versions)
1. In System Settings, click on **Notifications**
2. This will show you all apps and their notification settings
1. When you visit [Periskope](https://console.periskope.app) for the first time, you'll see a notification permission prompt
2. Click **Allow** to enable notifications
1. Go back to **System Settings** > **Notifications**
2. Scroll down and find your browser (e.g., **Chrome**, **Safari**, **Brave**, **Edge**)
3. Click on it and make sure notifications are enabled
4. Configure the alert style and other notification preferences as desired
1. Visit [Periskope](https://console.periskope.app)
2. Look for the notification settings in the top navigation bar
3. Make sure notifications are enabled in the Periskope app
If you've previously blocked notifications, you may need to reset the browser permissions by going to your browser's settings and clearing site permissions for Periskope.
In order to enable Periskope notifications on Windows device, you'll need to follow these steps -
In this doc, we provide instructions on how to enable notifications for Periskope on Windows browsers.
## Enable notifications for Periskope on Windows
1. Click on the **Start** button
2. Go to **Settings** > **System** > **Notifications**
3. Make sure **Notifications** are turned on globally
1. In the same Notifications settings page, scroll down to find your browser
2. Click on your browser (e.g., **Chrome**, **Edge**, **Brave**, **Firefox**)
3. Make sure notifications are enabled for your browser
1. Open your browser and go to [Periskope](https://console.periskope.app)
2. When prompted, click **Allow** to enable notifications for the Periskope website
1. In your browser, check the notification icon in the address bar
2. Make sure Periskope has permission to send notifications
1. In Windows Settings, you can also manage per-site notification settings
2. Make sure Periskope notifications are allowed
1. Visit [Periskope](https://console.periskope.app)
2. Look for the notification settings in the top navigation bar
3. Make sure notifications are enabled in the Periskope app
If you've previously blocked notifications, you may need to reset the browser permissions by going to your browser's settings (usually `chrome://settings/content/notifications` for Chrome or `edge://settings/content/notifications` for Edge) and removing Periskope from the blocked list.
For the best experience, make sure both Windows system notifications and browser notifications are enabled for Periskope.