Skip to content

feat(emails): add POST /emails/schedule for programmatic campaign creation - #310

Open
brayanjeshua wants to merge 1 commit into
GoHighLevel:mainfrom
brayanjeshua:feat/email-schedule-create-endpoint
Open

feat(emails): add POST /emails/schedule for programmatic campaign creation#310
brayanjeshua wants to merge 1 commit into
GoHighLevel:mainfrom
brayanjeshua:feat/email-schedule-create-endpoint

Conversation

@brayanjeshua

Copy link
Copy Markdown

Problem

Currently the Email Marketing API only exposes GET /emails/schedule (read campaigns) and POST /emails/builder (create templates). There is no endpoint to create or schedule email campaigns programmatically.

This forces developers to use the GHL UI manually for every campaign, even when they have fully automated workflows that create contacts, build HTML templates via API, and need to schedule sends without human intervention.

Proposed Solution

Add POST /emails/schedule with scope emails/schedule.write.

Request body (CreateScheduleDto)

FieldTypeRequiredDescription
locationIdstringSub-account ID
namestringCampaign name
subjectstringEmail subject line
campaignTypeenumdraft / send_now / schedule_later
htmlstringFull HTML body (or use templateId)
templateIdstringID from POST /emails/builder
fromstringSender email (verified domain)
fromNamestringSender display name
dateSchedulednumberUnix ms timestamp (required for schedule_later)
sendDaysstring[]Allowed send days
hasTrackingbooleanEnable open/click tracking
hasUtmTrackingbooleanAppend UTM params to links
enableResendToUnopenedbooleanAuto-resend to non-openers
resendInfoobjectResend subject + duration config

Example: schedule a campaign for Monday at 12:00 UTC

curl -X POST https://services.leadconnectorhq.com/emails/schedule \
-H "Authorization: Bearer pit-xxx" \
-H "Version: 2021-07-28" \
-H "Content-Type: application/json" \
-d '{ "locationId": "8Nua7uN3cDjUVlpiK9D0", "name": "Product Launch — Jul 14", "subject": "Something new is coming your way", "campaignType": "schedule_later", "status": "scheduled", "templateId": "6a526c938708da5288f5c149", "from": "info@yourdomain.com", "fromName": "Your Company", "dateScheduled": 1752487200000, "hasTracking": true, "hasUtmTracking": true }'

Real-world use case

Many agencies and SaaS builders using GHL as a white-label CRM need to:

  1. Import contacts via API ✅ (already works)
  2. Build email HTML via API ✅ (POST /emails/builder works)
  3. Create and schedule the campaign via API ❌ missing — this PR

Without step 3, the entire workflow requires manual UI intervention, defeating the purpose of API-first integration.

Changes

  • apps/emails.json: Added POST /emails/schedule endpoint, CreateScheduleDto request schema, and CreateScheduleSuccessfulResponseDto response schema.

Happy to iterate on the schema or add more examples. Thanks for maintaining the public API docs! 🙏

Add missing endpoint to create and schedule email marketing campaigns
via the API. Currently only GET /emails/schedule exists, making it
impossible to programmatically create draft or scheduled campaigns.
New endpoint: POST /emails/schedule
New scope: emails/schedule.write
New schemas: CreateScheduleDto, CreateScheduleSuccessfulResponseDto
Supports:
- Draft campaigns (campaignType: draft)
- Immediate send (campaignType: send_now)
- Scheduled send (campaignType: schedule_later + dateScheduled ms timestamp)
- Optional resend-to-unopened configuration
- HTML content directly or via templateId from POST /emails/builder
- UTM and open/click tracking flags

@orca-security-usorca-security-usBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orca Security Scan Summary

StatusCheckIssues by priority
Passed PassedInfrastructure as Codehigh 0 medium 0 low 6 info 22View in Orca
Passed PassedSASThigh 0 medium 0 low 0 info 0View in Orca
Passed PassedSecretshigh 0 medium 0 low 0 info 0View in Orca
Passed PassedVulnerabilitieshigh 0 medium 0 low 0 info 0View in Orca
🛡️ The following IaC misconfigurations have been detected
NAMEFILE
lowResponse on operations that should have a body has undefined schemaapps/emails.jsonView in code
lowResponse on operations that should have a body has undefined schemaapps/emails.jsonView in code
lowResponse on operations that should have a body has undefined schemaapps/emails.jsonView in code
lowResponse on operations that should have a body has undefined schemaapps/emails.jsonView in code
lowResponse on operations that should have a body has undefined schemaapps/emails.jsonView in code
lowResponse Code Missing (v3)apps/emails.jsonView in code
infoObject Without Required Propertyapps/emails.jsonView in code
infoObject Without Required Propertyapps/emails.jsonView in code
infoObject Without Required Propertyapps/emails.jsonView in code
infoObject Without Required Propertyapps/emails.jsonView in code
infoObject Without Required Propertyapps/emails.jsonView in code
infoObject Without Required Propertyapps/emails.jsonView in code
infoObject Without Required Propertyapps/emails.jsonView in code
infoDefault Invalidapps/emails.jsonView in code
infoTemplate Path With No Corresponding Path Parameterapps/emails.jsonView in code
infoTemplate Path With No Corresponding Path Parameterapps/emails.jsonView in code
infoTemplate Path With No Corresponding Path Parameterapps/emails.jsonView in code
infoComponents Object Fixed Field Key Improperly Namedapps/emails.jsonView in code
infoComponents Object Fixed Field Key Improperly Namedapps/emails.jsonView in code
infoComponents Object Fixed Field Key Improperly Namedapps/emails.jsonView in code
infoSecurity Requirement Object With Wrong Scopesapps/emails.jsonView in code
infoSecurity Requirement Object With Wrong Scopesapps/emails.jsonView in code
infoSecurity Requirement Object With Wrong Scopesapps/emails.jsonView in code
infoSecurity Requirement Object With Wrong Scopesapps/emails.jsonView in code
infoSecurity Requirement Object With Wrong Scopesapps/emails.jsonView in code
............

@brayanjeshua

Copy link
Copy Markdown
Author

Hi team 👋 Following up on this PR, open since mid-July. All security scans passed (Orca: IaC, SAST, Secrets, Vulnerabilities all SUCCESS), but the "Sonarqube Code Scan" check has been stuck in QUEUED since the PR was opened and never completed — likely because external forks don't have access to trigger the internal Jenkins pipeline. Would appreciate a review/merge, or guidance on getting that check unstuck. Thanks!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brayanjeshua