Switch from Crisp without rewriting your code

Pidge takes the same $crisp commands, checks signed emails the same way, and answers the main Crisp REST paths with Crisp's webhook format. For most sites the switch is one changed line in the page and a new base URL in the backend.

Checked against Pidge's code on 24 October 2026. Crisp's prices as of 16 October 2026.

The swap, in three steps

  1. Sign up, add your website in Pidge and list its domains. The website ID is on the Websites page in the inbox.
  2. In your page, keep window.$crisp = [] and CRISP_WEBSITE_ID. Put your Pidge website ID in CRISP_WEBSITE_ID.
  3. Change the script's address from Crisp's to Pidge's.

Here is Crisp's usual snippet, before and after:

<!-- before -->
<script>
  window.$crisp = [];
  window.CRISP_WEBSITE_ID = "your-crisp-website-id";
  (function () {
    var d = document, s = d.createElement("script");
    s.src = "https://client.crisp.chat/l.js";
    s.async = 1;
    d.getElementsByTagName("head")[0].appendChild(s);
  })();
</script>

<!-- after -->
<script>
  window.$crisp = [];
  window.CRISP_WEBSITE_ID = "your-pidge-website-id";
  (function () {
    var d = document, s = d.createElement("script");
    s.src = "https://app.pidge.chat/client/l.js";
    s.async = 1;
    d.getElementsByTagName("head")[0].appendChild(s);
  })();
</script>

Replace Crisp's script rather than adding Pidge next to it. Both read window.$crisp, so running the two together gives you two bubbles fighting over the same calls.

If you set up a chat domain like chat.example.com, the script address is https://chat.example.com/client/l.js instead. The code on the Websites page always shows the right one.

What keeps working on the page

Pidge installs one object as both window.$pidge and window.$crisp. Calls pushed before the script loads wait in the array and run once it has, as with Crisp.

Crisp commands in Pidge
Crisp callIn Pidge
["set", "user:email", [email, signature]]Works. The signature is optional and checked the same way. See signed emails.
["set", "user:nickname", [name]]Works.
["set", "session:data", [[[key, value], …]]]Works. One pair or a list of pairs. Values are stored as text.
["set", "session:segments", [[…], overwrite]]Works, including overwrite.
["do", "chat:open"], chat:close, chat:toggleWorks.
["do", "chat:show"], chat:hideWorks.
["do", "message:send", ["text", "…"]]Works for text. Other message types are ignored.
["do", "message:show", ["text", "…"]]Works for text. Other message types are ignored.
["do", "session:reset"]Works. Forgets the visitor and starts an empty chat.
$crisp.is(…)Works for chat:opened, chat:closed, chat:visible, chat:hidden and session:ongoing. Anything else returns false.

What the widget ignores

Pidge skips commands it doesn't know, without an error, as Crisp does. That includes:

One thing does break: Pidge has no $crisp.get(…). Calling it throws a TypeError, so search your code for $crisp.get and remove or guard those calls before you switch.

Signed emails

Crisp calls this identity verification. Pidge uses the same scheme: HMAC-SHA256 of the email, keyed with a secret, as lowercase hex. Your backend code stays as it is. Only the secret changes.

  1. In the Pidge inbox, open Developers and create a secret under Signed visitor emails for the website. It's shown once.
  2. Put it where your backend keeps the Crisp secret today.
  3. Keep pushing the email and signature as before:
$crisp.push(["set", "user:email", ["ada@example.com", "<signature from your server>"]]);

A signed email shows as verified in the inbox, and a customer who switches from phone to laptop stays in the same chat.

Your backend: the REST API

The paths, Basic auth and { error, reason, data } responses follow Crisp's REST API v1. Change the base URL and the key:

# before
CRISP_API=https://api.crisp.chat/v1
# after
CRISP_API=https://app.pidge.chat/v1

Keys are made on the Developers page, which only owners can open. Send the identifier as the user name and the key as the password. If your client sends X-Crisp-Tier: plugin, Pidge accepts it and ignores it. These paths exist, all under /v1/website/{website_id}:

Crisp REST paths in Pidge
PathWhat it does
GET /conversations/{page}Lists conversations, 20 a page.
GET /conversation/{session_id}One conversation.
GET /conversation/{session_id}/messagesMessages, with timestamp_before to page back.
POST /conversation/{session_id}/messageSends a message or a note.
DELETE /conversation/{session_id}/message/{fingerprint}Deletes a message.
PATCH /conversation/{session_id}/composeStarts or stops the typing indicator.
GET and PATCH /conversation/{session_id}/metaReads or changes name, email, data and segments.
GET /conversation/{session_id}/pages/{page}The pages the visitor opened, newest first.
GET and PATCH /conversation/{session_id}/stateReads or sets pending, unresolved or resolved.
PATCH /conversation/{session_id}/blockBlocks or unblocks the visitor.
GET /people/profiles/{page}Finds visitors by name or email.

That's the whole list. Crisp has many more endpoints, so if your integration calls one that isn't here, it gets an error. Tell us which one in the chat on this page. The API docs have the fields, limits and what each plan includes.

Webhooks

Add a webhook on the Developers page. The body is Crisp's shape, { website_id, event, data, timestamp }, and the X-Crisp-Signature header is hex HMAC-SHA256 of [timestamp;body]. verifyHook from Crisp's Node library accepts it. Your receiver needs the new signing secret and nothing else.

Pidge sends message:send, message:received, message:removed, session:set_email, session:set_nickname, session:set_data, session:set_segments, session:set_state, session:sync:pages and session:removed. You can also pick session:set_block, but it isn't sent yet. Failed deliveries are retried for about 23 hours.

What doesn't carry over

If you use any of these every day, Crisp is probably still the better fit. Pidge vs Crisp sets the two side by side.

What it costs

Crisp charges per workspace with a set number of seats: Free, then Mini at $45, Essentials at $95 or Plus at $295 a month, VAT not included. Pidge is free for one website with two people replying. After that it's $10 per website a month, or $100 a year, however many people answer.

Crisp's prices are from crisp.chat/en/pricing, checked 16 October 2026.

Next

Moving a site and something doesn't behave like Crisp did? Tell us in the chat on this page.

Try it on one site first

Start free

The free plan covers one website and two people replying. No card needed.