Hey Pingr API Documentation

// getting_started

Quickstart

Get your first WhatsApp login link sent in under 10 minutes. You'll need a Hey Pingr account and a WhatsApp number to connect.

No Meta Business API approval needed. Works with any regular WhatsApp number.

Step by step

1
Create your Hey Pingr account
Sign up at heypingr.com/signup. Start your 7-day free trial — no charges until the trial ends.
2
Connect your WhatsApp number
In the dashboard, go to Sessions → Add session. A QR code will appear. Open WhatsApp on your phone → Linked Devices → Link a device → scan the QR.
3
Copy your API key
Go to API keys in the dashboard. Copy your pk_live_ production key.
4
Send your first login link
Make a POST request to /v1/send with the user's number and your magic link.

Your first request

javascript
const Hey Pingr = require('hey-pingr');
const pingr = new Hey Pingr(process.env.PINGR_API_KEY);

const result = await pingr.messages.send({
  to: '919876543210', // digits only, with country code
  message: 'Click here to log in: https://yourapp.com/auth?token=abc123',
});

console.log(result.messageId); // msg_xK9p2mQr8nVs4wLj
console.log(result.rateLimitRemaining); // 499
python
import pingr

client = pingr.Hey Pingr("pk_live_your_key_here")

result = client.messages.send(
  to="919876543210", # digits only, with country code
  message="Click here to log in: https://yourapp.com/auth?token=abc123"
)

print(result["message_id"]) # msg_xK9p2mQr8nVs4wLj
print(result["rate_limit_remaining"]) # 499
bash
curl -X POST https://api.heypingr.com/v1/send \
  -H "X-API-Key: pk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"to":"919876543210","message":"Log in: https://yourapp.com/auth?t=abc"}'

Response

json
{
  "success": true,
  "message_id": "msg_xK9p2mQr8nVs4wLj",
  "to": "919876543210",
  "session_id": "sess_abc123",
  "rate_limit_remaining": 499
}
// authentication

Authentication

All API requests must include your API key in the X-API-Key header. You can find and manage your keys in the dashboard.

Never expose your API key in frontend/client-side code. Always call Hey Pingr from your backend server.

API key types

Production keys (pk_live_) send real WhatsApp messages and count toward your plan limits.

Test keys (pk_test_) simulate the full API response without sending actual messages. Use these in development and CI.

Authenticating requests

http
POST /v1/send HTTP/1.1
Host: api.heypingr.com
X-API-Key: pk_live_xK9p2mQr8nVs4wLj7dFhTbYcXeAuZo
Content-Type: application/json
// api_reference

POST /v1/send

Sends a WhatsApp message to a phone number. The message is delivered via your connected session.

POST https://api.heypingr.com/v1/send

Request body

ParameterTypeRequiredDescription
tostringrequiredRecipient phone — digits only with country code. e.g. 919876543210 (no +, no spaces)
messagestringrequiredThe message text to send. Supports WhatsApp formatting: *bold*, _italic_, ~strikethrough~.
session_idstringoptionalSession ID to use. Omit to auto-pick any connected session.

Response

json — 200 OK
{
  "success": true,
  "message_id": "msg_xK9p2mQr8nVs4wLj",
  "to": "919876543210",
  "session_id": "sess_abc123",
  "rate_limit_remaining": 499
}

Status codes

200Message sent successfully.
400Bad request — missing or invalid parameters.
401Unauthorized — invalid or missing API key.
429Rate limit exceeded — recipient is in cooldown window. Check Retry-After header.
// webhooks

Webhooks

Hey Pingr sends a POST request to your configured webhook URL whenever an event occurs — like an incoming message from a user.

Configure your webhook URL in Dashboard → Webhooks. Hey Pingr signs every request with HMAC-SHA256 — always verify the signature before processing.

Verifying signatures

javascript — hey-pingr SDK
const { verifyWebhook } = require('hey-pingr');

// Express — use express.raw() so body arrives as a Buffer
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  try {
    const payload = verifyWebhook(
      req.body,
      req.headers['x-pingr-signature'],
      process.env.PINGR_WEBHOOK_SECRET,
    );
    console.log(payload.event, payload.session_id);
    res.sendStatus(200);
  } catch (err) {
    res.sendStatus(400); // invalid signature
  }
});

Event payload — message.received

json
{
  "event": "message.received",
  "session_id": "sess_abc123",
  "from": {
    "phone": "919876543210",
    "jid": "919876543210@s.whatsapp.net",
    "is_group": false,
    "group_jid": null
  },
  "message": { "text": "hey login", "type": "text" },
  "timestamp": 1714825320000
}
// sdk

Node.js SDK

The official Node.js SDK wraps the Hey Pingr REST API with a clean, typed interface.

Installation

bash
npm install hey-pingr

Initialise

javascript
const Hey Pingr = require('hey-pingr');

const pingr = new Hey Pingr(process.env.PINGR_API_KEY);

Send a message

javascript
const result = await pingr.messages.send({
  to: '919876543210', // digits only, with country code
  message: `Your login link: https://yourapp.com/auth?token=${token}`,
});

console.log(result.messageId); // msg_abc123
console.log(result.rateLimitRemaining); // 498

Error handling

javascript
const { errors } = require('hey-pingr');

try {
  await pingr.messages.send({ to, message });
} catch (err) {
  if (err instanceof errors.PingrRateLimitError) {
    console.log(`Retry after ${err.retryAfter}s`);
  } else if (err instanceof errors.PingrAuthError) {
    console.log('Invalid API key');
  }
}

Verify webhooks

javascript
const { verifyWebhook } = require('hey-pingr');

// Express — use express.raw() to get a Buffer
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const payload = verifyWebhook(
    req.body,
    req.headers['x-pingr-signature'],
    process.env.PINGR_WEBHOOK_SECRET,
  );
  console.log(payload.event); // 'message.received'
  res.sendStatus(200);
});
// sdk

Python SDK

The official Python SDK for Hey Pingr. Supports both sync and async usage.

Installation

bash
pip install hey-pingr

# async support (FastAPI, asyncio)
pip install hey-pingr[async]

Usage

python
import pingr

client = pingr.Hey Pingr("pk_live_your_key_here")

result = client.messages.send(
  to="919876543210", # digits only, with country code
  message=f"Your login link: https://yourapp.com/auth?token={token}"
)

print(result["message_id"]) # msg_abc123
print(result["rate_limit_remaining"]) # 498

Async usage (FastAPI, asyncio)

python
import pingr

async def send_otp(phone: str, code: str):
  async with pingr.AsyncPingr(os.environ["PINGR_API_KEY"]) as client:
    result = await client.messages.send(
      to=phone,
      message=f"Your OTP is {code}"
    )
    return result["message_id"]

Verify webhooks

python
from pingr import verify_webhook, PingrWebhookError

# Flask example
@app.route("/webhook", methods=["POST"])
def webhook():
  try:
    payload = verify_webhook(
      request.get_data(),
      request.headers["x-pingr-signature"],
      os.environ["PINGR_WEBHOOK_SECRET"],
    )
    print(payload["event"]) # 'message.received'
    return "", 200
  except PingrWebhookError:
    return "", 400
// guides

Rate limits

Hey Pingr enforces two levels of rate limiting to protect your sessions and ensure fair use.

Per-recipient cooldown

By default, the same phone number cannot receive a message more than once every 60 seconds. This is configurable in Dashboard → Settings → Cooldown settings.

When a number is rate limited, the API returns a 429 response with a Retry-After header indicating seconds remaining.

Plan-level limits

PlanMessages/monthOverage rate
Starter10,000$0.002/msg
Growth70,000$0.0015/msg
Scale500,000$0.0008/msg

Handling 429 responses

javascript — hey-pingr SDK
const { errors } = require('hey-pingr');

try {
  await pingr.messages.send({ to: '919876543210', message: 'Your OTP is 123456' });
} catch (err) {
  if (err instanceof errors.PingrRateLimitError) {
    console.log(`Rate limited. Retry in ${err.retryAfter}s`);
    // Queue the message and schedule a retry
  }
}
// guides

Error handling

All errors return a JSON body under a detail key with an error code and human-readable message.

json — error response
{
  "detail": {
    "error": "rate_limit",
    "message": "Number +919876543210 is in cooldown. Try again in 47s.",
    "retry_after": 47
  }
}

Error codes

CodeHTTPDescription
invalid_key401The API key is missing or invalid.
missing_param422A required parameter is missing or malformed.
rate_limit429Recipient is in cooldown window. Check retry_after in the response.
quota_exceeded429Monthly message quota exhausted. Upgrade your plan.
no_session503No connected WhatsApp session found. Connect a number in the dashboard.
// sessions

Sessions & QR codes

A session represents a connected WhatsApp number on Hey Pingr's infrastructure. Each plan allows a different number of concurrent sessions.

Use a dedicated WhatsApp number for Hey Pingr — not your personal number. This keeps your auth traffic isolated.

Connecting a session

Go to Dashboard → Sessions → Add session. A QR code is generated. Open WhatsApp → Settings → Linked Devices → Link a device → scan the QR. The session goes live within seconds.

Session health monitoring

Hey Pingr monitors session health every 30 seconds. If a session disconnects (phone goes offline, WhatsApp logs out, etc.), a session.disconnected webhook event fires immediately and the dashboard shows a red status indicator.

// api_reference

GET /v1/sessions

Returns all sessions associated with your account and their current status.

GET https://api.heypingr.com/v1/sessions
json — 200 OK
{
  "sessions": [
    {
      "id": "main-login-bot",
      "name": "Main login bot",
      "number": "+919876543210",
      "status": "connected",
      "connectedAt": "2025-04-18T08:22:11.000Z",
      "messagesToday": 842
    }
  ]
}