API v1

Developer Documentation

Everything you need to integrate MetaBSP's WhatsApp API into your application

Contents
  • Getting Started

  • Authentication

  • Webhooks

  • Sending Messages

  • Template API

  • Node.js SDK

  • Python SDK

  • Error Codes

Getting Started


The MetaBSP API is a REST API that allows you to send and receive WhatsApp messages through Meta's WhatsApp Business Platform. All requests are made over HTTPS to our base URL.

Base URL
// Base URLhttps://meta.sanjusk.in/api
Quick Start

Follow these steps to send your first WhatsApp message:

  1. Create a MetaBSP account and connect your WhatsApp Business Account

  2. Navigate to Settings → API Keys and generate your first API key

  3. Use the API key to authenticate requests (Bearer token in Authorization header)

  4. Send a test message using the /messages endpoint

Authentication


MetaBSP uses API keys to authenticate requests. Include your API key in the Authorization header of every request as a Bearer token.

API Key Authentication
// Shellcurl -X GET https://meta.sanjusk.in/api/account \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
JWT Authentication (Server-to-Server)

For server-to-server integrations, you can use short-lived JWT tokens. Request a token using your API key, then use the JWT for subsequent requests.

// JavaScript// Step 1: Exchange API key for JWT
const response = await fetch('https://meta.sanjusk.in/api/auth/token', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ expires_in: 3600 }), // 1 hour
});
const { token } = await response.json();

// Step 2: Use JWT for requests
const messages = await fetch('https://meta.sanjusk.in/api/messages', {
  headers: { 'Authorization': `Bearer ${token}` },
});
API Key Scopes
messages:read
messages:write
templates:read
templates:write
contacts:read
contacts:write
webhooks:manage
account:read

Webhook Setup


Webhooks allow MetaBSP to push real-time events to your server when things happen — like a message being received or a delivery receipt arriving.

Configure a Webhook

Set up a webhook endpoint in your dashboard or via API:

// Shellcurl -X POST https://meta.sanjusk.in/api/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/whatsapp",
    "events": ["message.received", "message.delivered", "message.read", "template.approved"],
    "active": true
  }'
Verifying Webhook Signatures

Every webhook request includes a signature in the X-MetaBSP-Signature-256 header. Verify this signature to ensure the request is from MetaBSP.

// Node.jsconst crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature),
    Buffer.from(signature)
  );
}

// Express.js middleware
app.post('/webhooks/whatsapp', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-metabsp-signature-256'];
  const webhookSecret = process.env.METABSP_WEBHOOK_SECRET;

  if (!verifyWebhookSignature(req.body, signature, webhookSecret)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = JSON.parse(req.body);
  console.log('Event type:', event.type);

  // Process the event...

  res.status(200).json({ received: true });
});
Webhook Event Schema
// JSON{
  "id": "evt_01H8X3K2P9Q7R4M5N6T8W1Y2Z3",
  "type": "message.received",
  "created_at": "2025-06-15T10:30:00Z",
  "phone_number_id": "pn_abc123",
  "data": {
    "message_id": "wamid.HBgLMTY1MDUyOTAzNTYVAgARGBI...",
    "from": "+14155552671",
    "timestamp": "2025-06-15T10:29:58Z",
    "type": "text",
    "text": {
      "body": "Hello! I'd like to know more about your products."
    }
  }
}

Sending Messages


Send a Text Message
// Shellcurl -X POST https://meta.sanjusk.in/api/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number_id": "YOUR_PHONE_NUMBER_ID",
    "to": "+14155552671",
    "type": "text",
    "text": {
      "body": "Hello! Thanks for contacting us. How can we help you today?"
    }
  }'
Send a Template Message
// Shellcurl -X POST https://meta.sanjusk.in/api/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number_id": "YOUR_PHONE_NUMBER_ID",
    "to": "+14155552671",
    "type": "template",
    "template": {
      "name": "order_confirmation",
      "language": { "code": "en_US" },
      "components": [
        {
          "type": "body",
          "parameters": [
            { "type": "text", "text": "John" },
            { "type": "text", "text": "ORD-12345" },
            { "type": "text", "text": "$49.99" }
          ]
        }
      ]
    }
  }'
Send Media (Image)
// Shellcurl -X POST https://meta.sanjusk.in/api/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number_id": "YOUR_PHONE_NUMBER_ID",
    "to": "+14155552671",
    "type": "image",
    "image": {
      "link": "https://your-cdn.com/product-image.jpg",
      "caption": "Check out our new product!"
    }
  }'

Template API


List Templates
// JavaScriptconst response = await fetch(
  'https://meta.sanjusk.in/api/templates?status=APPROVED&limit=20',
  {
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
  }
);

const { templates, pagination } = await response.json();
// templates: [{ id, name, status, category, language, components }]
Create a Template
// JavaScriptconst response = await fetch('https://meta.sanjusk.in/api/templates', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'appointment_reminder',
    category: 'UTILITY',
    language: 'en_US',
    components: [
      {
        type: 'HEADER',
        format: 'TEXT',
        text: 'Appointment Reminder',
      },
      {
        type: 'BODY',
        text: 'Hi {{1}}, this is a reminder for your appointment on {{2}} at {{3}}. Reply CONFIRM to confirm or CANCEL to cancel.',
      },
      {
        type: 'FOOTER',
        text: 'Reply STOP to unsubscribe',
      },
    ],
  }),
});

const template = await response.json();
// { id, name, status: 'PENDING', ... }

Node.js SDK


Installation
// Shellnpm install @metabsp/sdk
Basic Usage
// JavaScript (Node.js)const { MetaBSP } = require('@metabsp/sdk');

const client = new MetaBSP({
  apiKey: process.env.METABSP_API_KEY,
  phoneNumberId: process.env.PHONE_NUMBER_ID,
});

// Send a text message
const result = await client.messages.send({
  to: '+14155552671',
  type: 'text',
  text: { body: 'Hello from MetaBSP Node.js SDK!' },
});

console.log('Message ID:', result.messageId);

// Listen for incoming messages
client.on('message.received', (event) => {
  console.log('Received:', event.data.text.body);
  // Reply to the sender
  client.messages.send({
    to: event.data.from,
    type: 'text',
    text: { body: 'Thanks for your message! We'll be in touch soon.' },
  });
});

// Start webhook listener (development only)
await client.webhooks.startLocalServer({ port: 3001 });
Template Sending
// JavaScript (Node.js)const result = await client.messages.sendTemplate({
  to: '+14155552671',
  templateName: 'order_shipped',
  languageCode: 'en_US',
  parameters: {
    body: ['John', 'ORD-12345', 'FedEx', 'Dec 20'],
  },
});

Python SDK


Installation
// Shellpip install metabsp
Basic Usage
// Pythonimport os
from metabsp import MetaBSP

client = MetaBSP(
    api_key=os.environ["METABSP_API_KEY"],
    phone_number_id=os.environ["PHONE_NUMBER_ID"],
)

# Send a text message
result = client.messages.send(
    to="+14155552671",
    type="text",
    text={"body": "Hello from MetaBSP Python SDK!"},
)
print(f"Message ID: {result.message_id}")

# Send a template
result = client.messages.send_template(
    to="+14155552671",
    template_name="order_confirmation",
    language_code="en_US",
    parameters={
        "body": ["Alice", "ORD-98765", "$120.00"],
    },
)

# List approved templates
templates = client.templates.list(status="APPROVED")
for template in templates:
    print(f"{template.name}: {template.status}")
Webhook Handler (Flask)
// Python (Flask)from flask import Flask, request, jsonify
from metabsp import verify_signature

app = Flask(__name__)
WEBHOOK_SECRET = os.environ["METABSP_WEBHOOK_SECRET"]

@app.route('/webhooks/whatsapp', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('X-MetaBSP-Signature-256')
    payload = request.get_data()

    if not verify_signature(payload, signature, WEBHOOK_SECRET):
        return jsonify({"error": "Invalid signature"}), 401

    event = request.get_json()

    if event["type"] == "message.received":
        message = event["data"]
        print(f"Received message from {message['from']}: {message['text']['body']}")

    return jsonify({"received": True}), 200

Error Codes


All API errors return a JSON body with an error code and message. HTTP status codes follow standard conventions.

HTTP StatusError CodeDescription
400
INVALID_REQUESTRequest body is malformed or missing required fields
401
UNAUTHORIZEDMissing or invalid API key
403
FORBIDDENAPI key does not have permission for this action
404
NOT_FOUNDThe requested resource was not found
422
VALIDATION_ERRORRequest failed validation (details in errors array)
429
RATE_LIMITEDToo many requests. Check Retry-After header
500
INTERNAL_ERRORInternal server error. Contact support if persistent
503
SERVICE_UNAVAILABLEMetaBSP or WhatsApp API is temporarily unavailable