Skip to main content
osky
How to Remove Students from Specific Courses in SendPulse via Your WhatsApp Bot

How to Remove Students from Specific Courses in SendPulse via Your WhatsApp Bot

Until recently, removing a student from SendPulse Academy meant kicking them out of every single course at once. No precision, no control — just a blanket removal. That changed. Now you can select exactly which courses a student gets removed from, and the system explicitly warns you that their progress in those courses will be permanently deleted. This tutorial walks you through connecting that functionality to your WhatsApp bot so the entire process runs automatically, without anyone having to log into the dashboard every time a student cancels or changes plans.

Flujo de automatizacion conectando WhatsApp con API de SendPulse

The most common production use case: a user sends a WhatsApp message asking to cancel their subscription to a specific course. Your bot receives that, identifies the contact, calls the SendPulse API to remove them from the correct course, and confirms the cancellation. No human intervention required. In 2026, that's the baseline expectation for any serious academy operation.


Requirements

  • Active SendPulse account with Academy module enabled
  • WhatsApp bot configured in SendPulse (Chatbot Builder) or external integration via SendPulse REST API
  • API Key and API Secret from your SendPulse account (Settings → API)
  • Node.js 20+ if you're using the snippets in this tutorial, or any language capable of HTTP requests
  • Access to the Academy panel to verify course IDs

Step 1 — Get Your SendPulse API Access Token

Before making any API calls, you need a Bearer token. SendPulse uses OAuth 2.0 with client_credentials.

curl -X POST https://api.sendpulse.com/oauth/access_token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "YOUR_API_KEY",
    "client_secret": "YOUR_API_SECRET"
  }'

The response gives you an access_token valid for one hour. Cache it with a TTL of 3500 seconds. Never hardcode it in your source — use environment variables.

// .env
SENDPULSE_CLIENT_ID=your_api_key
SENDPULSE_CLIENT_SECRET=your_api_secret

Step 2 — Get the Course IDs from Academy

In your SendPulse dashboard, go to Academy → Courses. Each course has a numeric ID visible in the URL when you open it: academy.sendpulse.com/course/XXXXXX/edit. Write those down — you'll need them for the removal call.

If you want to do this programmatically, you can list courses via the API:

const res = await fetch('https://api.sendpulse.com/academy/courses', {
  headers: { Authorization: `Bearer ${token}` }
});
const { data } = await res.json();
// data is an array with id, title, etc.

Step 3 — Find the Student ID by Their WhatsApp Phone Number

When a user sends a message from WhatsApp, your bot receives their phone number. You need to cross-reference that with the contact in SendPulse to get their student_id in Academy.

async function getStudentByPhone(phone, token) {
  const res = await fetch(
    `https://api.sendpulse.com/addressbooks/contacts/get/by/variable`,
    {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        variable_name: 'phone',
        variable_value: phone
      })
    }
  );
  const data = await res.json();
  return data?.data?.[0]?.id ?? null;
}

Production warning: Phone numbers from WhatsApp arrive in international format without + (e.g., 5215512345678). Always normalize before searching. A format mismatch will give you false negatives and the student will never be removed.


Step 4 — Call the Endpoint to Remove the Student from Selected Courses

This is the new functionality SendPulse enabled. The endpoint accepts an array of course_ids so the removal is surgical.

async function removeStudentFromCourses(studentId, courseIds, token) {
  const res = await fetch(
    `https://api.sendpulse.com/academy/students/${studentId}/remove`,
    {
      method: 'DELETE',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        course_ids: courseIds // e.g. [1023, 1087]
      })
    }
  );

  if (!res.ok) {
    const err = await res.json();
    throw new Error(`Removal error: ${JSON.stringify(err)}`);
  }

  return await res.json();
}

Critical warning: The student's progress in those courses is deleted permanently and irreversibly. There is no recycle bin. If your logic has a bug and sends the wrong course_id, you've lost that student's data with no way to recover it. Validate twice before executing.


Step 5 — Wire This Into Your WhatsApp Bot Flow

In SendPulse's Chatbot Builder, create a flow with these steps:

  1. Trigger: The user types something like "cancel course" or "unsubscribe"
  2. Action — Input: Ask them which course they want to leave (show a quick reply button menu with your course names)
  3. Action — Webhook: Call your backend with the user's phone number and the selected course
  4. Your backend: Execute steps 1–4 from this tutorial
  5. Action — Send message: Confirm the cancellation to the user

If you're using n8n or Make as middleware, the HTTP Request node in n8n handles these calls directly. Just map the incoming webhook variables to the request body fields.

// Example payload your bot sends to your backend
{
  "phone": "5215512345678",
  "course_id": 1023,
  "confirm": true
}

Step 6 — Handle Errors Gracefully

In production, these things happen:

  • The student doesn't exist in Academy (registered but never activated the course)
  • The token expired mid-request
  • The course_id doesn't match any active course
try {
  const studentId = await getStudentByPhone(phone, token);
  if (!studentId) {
    return bot.sendMessage(phone, 'We could not find your account. Please contact support.');
  }
  await removeStudentFromCourses(studentId, [courseId], token);
  bot.sendMessage(phone, `Done — you have been removed from the course. Your progress has been deleted.`);
} catch (err) {
  console.error(err);
  bot.sendMessage(phone, 'Something went wrong. Please try again or contact support.');
}

Final Production Warnings

  • Mandatory logging: Record every deletion with timestamp, phone, student_id, and course_ids. If something goes wrong, you need an audit trail.
  • Double confirmation: Before executing the DELETE, send the user a confirmation message: "Are you sure you want to cancel course X? Reply YES to continue." One extra step prevents mistakes and post-removal disputes.
  • Rate limits: The SendPulse API has rate limits. If many users cancel simultaneously, implement a queue (BullMQ, Redis) instead of direct synchronous calls.
  • Internal notifications: Send an internal alert (Slack, email, whatever you use) every time a removal is executed. Your team should know who left and from which course.

With this in place, you have a complete flow — from the moment the user sends a message to the moment they're out of the course — without anyone touching the dashboard manually.