Pusher-Compatible API

The Free, Pusher-Compatible Realtime API

Drop-in Pusher alternative — free to use, no per-message billing.

Apinator is API-compatible with Pusher — keep your channels, your auth flow, and your client code. And it is free to use: no per-message billing, no connection tiers, no surprise invoices when traffic spikes. Migrate in minutes.

Pusher-Compatible API

Same channel types, auth flow, and event model as Pusher. Swap the client library — nothing else changes.

No Per-Message Billing

Pusher charges per message and connection. Apinator is free to use, with no metered fees, no peak-connection overage, and no surprise invoices when traffic spikes.

Free Tier Built for Production

Presence, private channels, webhooks, and multi-region are included — not gated behind a paid plan. No credit card required.

Multi-Region (EU + US)

Choose the region for your app — EU or US — so connections stay close to your users and sensitive data stays in its jurisdiction.

Full Feature Parity

Public, private, and presence channels. Client events. Webhooks. HMAC auth. Everything you rely on Pusher for, without the per-unit bill.

Drop-In Migration

Replace pusher-js with @apinator/client and your existing channel code keeps working. Most teams migrate in under 30 minutes.

Apinator vs Pusher

FeatureApinatorPusher
Pricing modelFreePer-message / per-connection
Free-tier connections500100
Free-tier messages / day500,000200,000
Per-message overageNoneYes
Connection overageNoneYes
Private channels
Presence channels
Client events
Webhooks
Multi-regionEnterprise only
EU data residencyAdd-on

Drop-In Migration

Replace pusher-js with @apinator/client — the channel and event API is identical. One import, done.

migration.js
// Before — pusher-js import Pusher from 'pusher-js' const pusher = new Pusher('APP_KEY', { cluster: 'us2' }) const ch = pusher.subscribe('orders') ch.bind('update', (data) => renderOrder(data)) // After — @apinator/client (identical API, fully managed) import { RealtimeClient } from '@apinator/client' const client = new RealtimeClient('APP_KEY', { host: 'wss://rt.apinator.io' }) const ch = client.subscribe('orders') ch.bind('update', (data) => renderOrder(data))

Pricing: Metered vs. Free

Where the cost difference actually comes from.

Pusher's pricing is metered. You pay for concurrent connections and for messages, and the bill climbs every time your app gets busier. Cross a plan threshold — a product launch, a viral moment, a seasonal spike — and the invoice follows. Realtime becomes a variable cost you have to forecast, cap, and explain.

Apinator removes the meter. The platform is free to use, with no per-message overage and no peak-connection charge. The current free tier covers 500 concurrent connections, 500,000 messages per day, 100 channels, and presence tracking up to 500 members per channel. Presence, private channels, webhooks, and EU/US regions are all included rather than gated behind a paid plan — so the same workload that grows your Pusher bill leaves your Apinator bill at zero.

If you just need an endpoint to point a client at, the free WebSocket server overview covers the basics. If region and data residency matter, see managed WebSocket infrastructure, and the how WebSockets scale guide explains what runs underneath.

Step-by-Step Migration from Pusher

Most teams move over in under 30 minutes. The client swap above is step one — here is the server side and channel auth.

1. Point your server SDK at Apinator

Server-side publishing uses the same trigger() signature as the Pusher server library. Swap the import and credentials — the channel name, event name, and payload stay identical.

publish.js
// Before — pusher (server SDK) import Pusher from 'pusher' const pusher = new Pusher({ appId, key, secret, cluster: 'us2' }) await pusher.trigger('orders', 'update', { id: 1042 }) // After — @apinator/server (identical trigger signature) import { ApinatorServer } from '@apinator/server' const apinator = new ApinatorServer({ appId, key, secret }) await apinator.trigger('orders', 'update', { id: 1042 })

2. Update the private & presence channel auth endpoint

Private and presence channels authorize through an HMAC-signed endpoint on your backend — the same scheme Pusher uses. Swap the helper; the request/response shape is the same.

auth.js
// Before — pusher.authorizeChannel app.post('/auth', (req, res) => { const auth = pusher.authorizeChannel(req.body.socket_id, req.body.channel_name) res.send(auth) }) // After — apinator.authorizeChannel (same HMAC scheme) app.post('/auth', (req, res) => { const auth = apinator.authorizeChannel(req.body.socket_id, req.body.channel_name) res.send(auth) })

3. Repoint the client host and deploy

Set the client host to wss://rt.apinator.io, choose your region (EU or US) when you create the app, and deploy. Existing channel names, event bindings, and presence logic keep working unchanged — there is no data to migrate because realtime events are transient.

When to Choose Pusher vs. Apinator

An honest read. Both are hosted realtime platforms with the same core primitives; the decision usually comes down to billing model and ecosystem maturity.

Stick with Pusher when

  • You depend on a Pusher-specific add-on or dashboard integration that has no Apinator equivalent yet.
  • Your organization already has procurement, SLAs, and support contracts in place with Pusher and switching cost outweighs the savings.
  • You need a region Apinator does not currently offer (today Apinator runs EU and US data planes).

Switch to Apinator when

  • Your realtime bill scales with traffic and you want a predictable $0 instead of per-message and per-connection metering.
  • You want presence, private channels, webhooks, and multi-region included rather than gated behind higher plans.
  • You need EU data residency without it being a paid add-on.
  • You want a drop-in path: keep your channel code, swap the client and server imports — see the migration steps above.

Frequently Asked Questions

Ready to get started?

Completely free, no credit card required. Deploy in minutes.