Scheduling Campaigns
Scheduling Campaigns
A SCHEDULING campaign is designed specifically for booking meetings with candidates. Unlike other campaign types, SCHEDULING campaigns focus solely on getting candidates to book a time slot—no screening questions, no rejection flows.
Overview
SCHEDULING campaigns:
- Send a booking link to candidates
- Auto-close when a booking is confirmed (or after 1 week if no booking)
- Support SMS, WhatsApp, and Email channels
- Require a
calendarMeetingTemplateIdfor booking configuration
Quick Start
curl -X POST "https://api.joinpopp.com/v1/campaigns" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-organization-id: YOUR_ORGANIZATION_ID" \
-H "Content-Type: application/json" \
-d '{
"campaignType": "SCHEDULING",
"channel": "SMS",
"campaignTitle": "Interview Scheduling",
"campaignDescription": "Schedule interviews with engineering candidates",
"calendarMeetingTemplateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"customTemplatedMessage": "Hi {{CANDIDATE_FIRST_NAME}}, please book your interview here: {{MEETING_URL}}. Reply STOP to opt out.",
"agentName": "Alex",
"agentTone": "FRIENDLY"
}'Note:
closingMethodis automatically set toCALENDAR_MEETING_INTEGRATIONfor SCHEDULING campaigns—you don't need to specify it.
Choosing the AI Agent
There is no agentId field on campaign creation. An agent cannot be referenced by ID — the API resolves one from what else you send:
| What you send | What Popp does |
|---|---|
agentName and agentTone | Reuses your organization's default agent if both match it; otherwise creates a new agent with that name and tone |
| Neither | Falls back to your organization's default agent — only if one is configured, otherwise a 404 (see below) |
Send both. The fallback depends on your organization having a default agent, and not every organization does — so an integration that relies on it works for some organizations and 404s for others.
The two fields travel together — sending one without the other is a 400:
agentTone is required when agentName is provided
agentName is required when agentTone is provided
The 404 Agent not found trap
404 Agent not found trapOmit agentName and agentTone and there are two ways it can fail, depending on how your organization is set up:
| Organization state | Response |
|---|---|
| Config exists, but no default agent on it | 404 Agent not found |
| No organization config at all | 404 Organization config not found |
Either way the 404 reads like a resource you referenced is missing — a bad campaign or meeting-template ID. It is not. It means no agent could be resolved, and the fix is to add agentName and agentTone (as in Quick Start) — not to hunt for an ID you failed to pass.
For API-led integrations, naming the agent explicitly is the reliable option. agentName takes up to 3 words of Unicode letters; agentTone is one of CASUAL, ENCOURAGING, FRIENDLY, MOTIVATIONAL, NEUTRAL, PROFESSIONAL.
Field Restrictions
SCHEDULING campaigns have specific field restrictions to keep the flow focused on booking.
Disallowed Fields
The following fields are NOT allowed for SCHEDULING campaigns:
| Field | Reason |
|---|---|
questions | No screening questions—scheduling only |
rejectionMessage | No rejection flow for scheduling |
closingMessage | Booking confirmation serves as the closing message |
meetingUrl | Conflicts with calendarMeetingTemplateId booking URL |
customMessage | Not applicable for scheduling campaigns |
closingMethod | Automatically set to CALENDAR_MEETING_INTEGRATION (ignored if provided) |
Example Error Response
If you include a disallowed field:
{
"error": "closingMessage is not allowed for SCHEDULING campaigns - booking confirmation serves as the closing message"
}Channel-Specific Rules
WhatsApp
WhatsApp SCHEDULING campaigns require an approved template (openingMessageTemplateId). Custom messages are not allowed.
| Field | Required | Notes |
|---|---|---|
openingMessageTemplateId | ✅ Required | Must reference a SCHEDULING template with {{MEETING_URL}} and STOP keyword |
customTemplatedMessage | ❌ Not allowed | WhatsApp requires approved templates |
Template Requirements:
- Template must be of type
SCHEDULING - Template content must include
{{MEETING_URL}}placeholder - Template content must include STOP opt-out instruction
- Template must belong to your organization
Example Request (WhatsApp):
{
"campaignType": "SCHEDULING",
"channel": "WHATSAPP",
"campaignTitle": "Technical Interview",
"campaignDescription": "Schedule technical interviews",
"closingMethod": "CALENDAR_MEETING_INTEGRATION",
"calendarMeetingTemplateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"openingMessageTemplateId": "f6a7b8c9-0123-4567-89ab-cdef01234567"
}SMS
SMS SCHEDULING campaigns require either openingMessageTemplateId OR customTemplatedMessage (not both).
| Field | Required | Notes |
|---|---|---|
openingMessageTemplateId | One of these required | Must reference a SCHEDULING template with {{MEETING_URL}} and STOP |
customTemplatedMessage | One of these required | Must include {{MEETING_URL}} placeholder and STOP opt-out instruction |
Template Requirements (if using templateId):
- Template must be of type
SCHEDULING - Template content must include
{{MEETING_URL}}placeholder - Template content must include STOP opt-out instruction
- Template must belong to your organization
Custom Template Requirements (if using customTemplatedMessage):
- Must include
{{MEETING_URL}}placeholder - Must include STOP opt-out instruction
Available Placeholders (for SMS and Email)
{{CANDIDATE_FIRST_NAME}}- Candidate's first name{{MEETING_URL}}- Booking link (required in message body){{MEETING_TITLE}}- Meeting title from calendar template{{AGENT_NAME}}- AI agent's name{{JOB_TITLE}}- Job title{{EMPLOYER_NAME}}- Employer name{{LOCATION}}- Job location{{ORGANIZATION_NAME}}- Organization name
Example Request (SMS with Template ID):
{
"campaignType": "SCHEDULING",
"channel": "SMS",
"campaignTitle": "Phone Screen Scheduling",
"campaignDescription": "Schedule phone screens with candidates",
"closingMethod": "CALENDAR_MEETING_INTEGRATION",
"calendarMeetingTemplateId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"openingMessageTemplateId": "0a1b2c3d-4e5f-6789-abcd-ef0123456789"
}Example Request (SMS with Custom Template):
{
"campaignType": "SCHEDULING",
"channel": "SMS",
"campaignTitle": "Phone Screen Scheduling",
"campaignDescription": "Schedule phone screens with candidates",
"closingMethod": "CALENDAR_MEETING_INTEGRATION",
"calendarMeetingTemplateId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"customTemplatedMessage": "Hi {{CANDIDATE_FIRST_NAME}}, we'd love to chat! Book your interview here: {{MEETING_URL}}\n\nReply STOP to opt out."
}Email
Email SCHEDULING campaigns require customTemplatedMessage. Template IDs are not supported for Email.
| Field | Required | Notes |
|---|---|---|
customTemplatedMessage | ✅ Required | Must include {{MEETING_URL}} placeholder and STOP opt-out instruction |
customTemplatedSubjectLine | ✅ Required | Email subject line (supports placeholders) |
openingMessageTemplateId | ❌ Not allowed | Email templates not supported via templateId |
Custom Template Requirements:
customTemplatedMessagemust include{{MEETING_URL}}placeholdercustomTemplatedMessagemust include STOP opt-out instructioncustomTemplatedSubjectLineis required for Email SCHEDULING campaigns
Note: Email supports the same placeholders as SMS (see Available Placeholders above).
Custom Subject Line (Email only):
You can also specify a custom email subject line using customTemplatedSubjectLine. This field supports the same placeholders as the message body (but none are required).
Example Request (Email with Custom Subject):
{
"campaignType": "SCHEDULING",
"channel": "EMAIL",
"campaignTitle": "Executive Interview",
"campaignDescription": "Schedule executive interviews",
"closingMethod": "CALENDAR_MEETING_INTEGRATION",
"calendarMeetingTemplateId": "c3d4e5f6-a7b8-9012-cdef-345678901234",
"customTemplatedSubjectLine": "Schedule Your {{MEETING_TITLE}} with {{ORGANIZATION_NAME}}",
"customTemplatedMessage": "Hello {{CANDIDATE_FIRST_NAME}},\n\nWe're excited to move forward with your application! Please select a time that works for you: {{MEETING_URL}}\n\nLooking forward to speaking with you.\n\nBest regards,\n{{AGENT_NAME}}\n\nReply STOP to unsubscribe."
}Nudge Settings
You can customize the follow-up nudge timing for any campaign type (not just SCHEDULING) by providing nudgeSettings when creating a campaign.
{
"campaignType": "SCHEDULING",
"nudgeSettings": [
{ "delayHours": 12 },
{ "delayHours": 48 }
]
}Each entry in the array represents one follow-up nudge. The delayHours field specifies the wait time since the previous message. The array length determines the total number of nudges.
| Configuration | Behavior |
|---|---|
"nudgeSettings": [{"delayHours": 24}, {"delayHours": 48}] | 2 nudges: first at 24h, second at 48h after the first |
"nudgeSettings": [] | Disables nudging entirely |
"nudgeSettings": null (or omitted) | Uses default behavior (3 nudges at 24h intervals) |
"disableNudging": true | Disables nudging (shortcut for empty array) |
Note: You cannot set both
disableNudging: trueand a non-emptynudgeSettingsarray. This returns a 400 error.
Default Behaviors
Auto-Close Duration
SCHEDULING campaigns default to 168 hours (1 week) for timeToAutoCloseConversationsInHours if not specified.
Note: If a candidate books a meeting, the conversation closes immediately upon booking confirmation. The 1-week timeout only applies if no booking is made.
Calendar Meeting Template
A calendarMeetingTemplateId is required for SCHEDULING campaigns. You can provide it:
- On the campaign - All conversations use this template
- On each conversation - Override the campaign-level template per conversation
If neither is provided, the API returns an error:
{
"message": "calendarMeetingTemplateId is required for SCHEDULING campaigns. Provide it on the campaign or in the conversation payload."
}Opening Message Override
The openingMessage field is not supported for SCHEDULING campaigns at the conversation level. This is because SCHEDULING campaigns require variable substitution (e.g., {{MEETING_URL}}, {{CANDIDATE_FIRST_NAME}}), which is only processed for campaign-level customTemplatedMessage.
To customize messages for SCHEDULING campaigns, use customTemplatedMessage and customTemplatedSubjectLine when creating the campaign.
Validation Summary
| Channel | customTemplatedMessage | openingMessageTemplateId | customTemplatedSubjectLine |
|---|---|---|---|
| ❌ Not allowed | ✅ Required (must include {{MEETING_URL}} and STOP) | ❌ Not applicable | |
| SMS | One of these required (must include {{MEETING_URL}} and STOP) | One of these required | ❌ Not applicable |
✅ Required (must include {{MEETING_URL}} and STOP) | ❌ Not allowed | ✅ Required |
The STOP opt-out requirement
Every SCHEDULING customTemplatedMessage must contain a STOP opt-out instruction, on both SMS and Email. This is a hard validation — the literal word STOP has to appear in the message text. Omitting it returns 400:
{
"message": "customTemplatedMessage must include STOP opt-out instruction for SCHEDULING campaigns"
}A trailing Reply STOP to opt out. satisfies it. The check matches the whole word STOP case-sensitively, so lowercase "stop" in ordinary prose does not count.
Templates referenced by openingMessageTemplateId must carry {{MEETING_URL}} and a STOP instruction in their own content.
Complete Example
Create a SCHEDULING Campaign (SMS)
curl -X POST "https://api.joinpopp.com/v1/campaigns" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-organization-id: YOUR_ORGANIZATION_ID" \
-H "Content-Type: application/json" \
-d '{
"campaignType": "SCHEDULING",
"channel": "SMS",
"campaignTitle": "Engineering Interview",
"campaignDescription": "Schedule interviews for senior engineering roles",
"closingMethod": "CALENDAR_MEETING_INTEGRATION",
"calendarMeetingTemplateId": "d4e5f6a7-b8c9-0123-def4-567890123456",
"agentName": "Sarah",
"agentTone": "FRIENDLY"
}'Create a Conversation
curl -X POST "https://api.joinpopp.com/v1/conversations" \
-H "x-api-key: YOUR_API_KEY" \
-H "x-organization-id: YOUR_ORGANIZATION_ID" \
-H "Content-Type: application/json" \
-d '{
"campaignId": "campaign-id-from-above",
"phoneNumber": "+14155551234",
"firstName": "John",
"lastName": "Doe"
}'Related Guides
- Meeting Templates - Configure meeting duration, participants, and rules
- Auto-Schedule Conversations - Create conversations that book meetings
- Scheduling with Availability Collection - End-to-end guide for scheduling when Popp collects interviewer availability
- Scheduling Events - Webhook payloads for booking events
Updated 1 day ago
