Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion api-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -1718,7 +1718,7 @@
"type": "string"
},
"listIds": {
"description": "To create a blast campaign, set <code>listIds</code> to an array of list IDs to which the campaign should be sent. To create a triggered campaign, omit <code>listIds</code> from the request body.",
"description": "To create a blast campaign, set <code>listIds</code> to a non-empty array of list IDs to which the campaign should be sent. To create a triggered campaign, omit <code>listIds</code> from the request body.",
"items": {
"format": "int64",
"type": "integer"
Expand All @@ -1729,6 +1729,11 @@
"description": "The name to use in Iterable for the new campaign.",
"type": "string"
},
"scheduleSend": {
"description": "Whether to immediately schedule the blast campaign for sending. Defaults to <code>true</code>. Set to <code>false</code> to create the campaign without scheduling it (the campaign can be scheduled later using <code>POST /api/campaigns/{campaignId}/schedule</code>). Only applies to blast campaigns.",
"example": false,
"type": "boolean"
},
"sendAt": {
"description": "A scheduled send time for a new blast campaign, up to 21 days in the future. Format: <code>YYYY-MM-DD HH:MM:SS</code> (UTC). For more details, see our <a href=\"https://support.iterable.com/hc/articles/204780579#post-api-campaigns-create\">API Overview</a>.",
"type": "string"
Expand Down Expand Up @@ -3857,6 +3862,8 @@
"webPushSend",
"webPushClick",
"webPushSendSkip",
"rcsSend",
"rcsSendSkip",
"emailSubscribe",
"emailUnSubscribe",
"purchase",
Expand Down Expand Up @@ -7175,6 +7182,8 @@
"webPushSend",
"webPushClick",
"webPushSendSkip",
"rcsSend",
"rcsSendSkip",
"emailSubscribe",
"emailUnSubscribe",
"purchase",
Expand Down Expand Up @@ -7329,6 +7338,8 @@
"webPushSend",
"webPushClick",
"webPushSendSkip",
"rcsSend",
"rcsSendSkip",
"emailSubscribe",
"emailUnSubscribe",
"purchase",
Expand Down
6 changes: 3 additions & 3 deletions src/client/campaigns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
ArchiveCampaignsResponseSchema,
CampaignMetricsResponse,
CancelCampaignParams,
CreateAndScheduleCampaignParams,
CreateBlastCampaignParams,
CreateCampaignResponse,
CreateCampaignResponseSchema,
CreateTriggeredCampaignParams,
Expand Down Expand Up @@ -76,8 +76,8 @@ export function Campaigns<T extends Constructor<BaseIterableClient>>(Base: T) {
return this.validateResponse(response, GetCampaignResponseSchema);
}

async createAndScheduleCampaign(
params: CreateAndScheduleCampaignParams
async createBlastCampaign(
params: CreateBlastCampaignParams
): Promise<CreateCampaignResponse> {
const response = await this.client.post("/api/campaigns/create", params);
return this.validateResponse(response, CreateCampaignResponseSchema);
Expand Down
12 changes: 9 additions & 3 deletions src/types/campaigns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ const campaignDataFieldsSchema = z
);

// Create and schedule a blast campaign
export const CreateAndScheduleCampaignParamsSchema = z.object({
export const CreateBlastCampaignParamsSchema = z.object({
name: z
.string()
.describe("The name to use in Iterable for the new campaign"),
Expand All @@ -164,6 +164,12 @@ export const CreateAndScheduleCampaignParamsSchema = z.object({
.array(z.number())
.min(1)
.describe("Array of list IDs to which the campaign should be sent"),
scheduleSend: z
.boolean()
.default(false)
.describe(
"Whether to immediately schedule the blast campaign for sending. Set to true to schedule the campaign on creation. When false, the campaign can be scheduled later using POST /api/campaigns/{campaignId}/schedule."
),
sendAt: IterableDateTimeSchema.describe(
"Scheduled send time (YYYY-MM-DD HH:MM:SS UTC)"
),
Expand All @@ -188,8 +194,8 @@ export const CreateAndScheduleCampaignParamsSchema = z.object({
.describe("Array of suppression list IDs"),
});

export type CreateAndScheduleCampaignParams = z.infer<
typeof CreateAndScheduleCampaignParamsSchema
export type CreateBlastCampaignParams = z.input<
typeof CreateBlastCampaignParamsSchema
>;

// Create a triggered campaign
Expand Down
2 changes: 2 additions & 0 deletions src/types/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export const StartExportJobParamsSchema = z.object({
"webPushSend",
"webPushClick",
"webPushSendSkip",
"rcsSend",
"rcsSendSkip",
"emailSubscribe",
"emailUnSubscribe",
"purchase",
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/campaigns.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe("Campaign Management Integration Tests", () => {
sendAt: string;
}) => {
const createResponse = await retryRateLimited(
() => withTimeout(client.createAndScheduleCampaign(params)),
() => withTimeout(client.createBlastCampaign(params)),
`Create blast campaign: ${params.name}`
);
return createResponse.campaignId;
Expand Down
22 changes: 11 additions & 11 deletions tests/unit/campaigns.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
ArchiveCampaignsParamsSchema,
CampaignDetailsSchema,
CancelCampaignParamsSchema,
CreateAndScheduleCampaignParamsSchema,
CreateBlastCampaignParamsSchema,
CreateTriggeredCampaignParamsSchema,
DeactivateTriggeredCampaignParamsSchema,
GetCampaignMetricsParamsSchema,
Expand Down Expand Up @@ -781,10 +781,10 @@ describe("Campaign Management", () => {
).toThrow(); // invalid type
});

it("should validate createAndScheduleCampaign parameters", () => {
it("should validate createBlastCampaign parameters", () => {
// Valid parameters - all required fields
expect(() =>
CreateAndScheduleCampaignParamsSchema.parse({
CreateBlastCampaignParamsSchema.parse({
name: "Test Campaign",
templateId: 123,
listIds: [456],
Expand All @@ -794,7 +794,7 @@ describe("Campaign Management", () => {

// Valid with optional fields
expect(() =>
CreateAndScheduleCampaignParamsSchema.parse({
CreateBlastCampaignParamsSchema.parse({
name: "Test Campaign",
templateId: 123,
listIds: [456, 789],
Expand All @@ -809,7 +809,7 @@ describe("Campaign Management", () => {

// Missing sendAt
expect(() =>
CreateAndScheduleCampaignParamsSchema.parse({
CreateBlastCampaignParamsSchema.parse({
name: "Test Campaign",
templateId: 123,
listIds: [456],
Expand All @@ -818,7 +818,7 @@ describe("Campaign Management", () => {

// Missing listIds
expect(() =>
CreateAndScheduleCampaignParamsSchema.parse({
CreateBlastCampaignParamsSchema.parse({
name: "Test Campaign",
templateId: 123,
sendAt: "2026-03-01 10:00:00",
Expand All @@ -827,7 +827,7 @@ describe("Campaign Management", () => {

// Empty listIds
expect(() =>
CreateAndScheduleCampaignParamsSchema.parse({
CreateBlastCampaignParamsSchema.parse({
name: "Test Campaign",
templateId: 123,
listIds: [],
Expand All @@ -837,7 +837,7 @@ describe("Campaign Management", () => {

// Missing name
expect(() =>
CreateAndScheduleCampaignParamsSchema.parse({
CreateBlastCampaignParamsSchema.parse({
templateId: 123,
listIds: [456],
sendAt: "2026-03-01 10:00:00",
Expand All @@ -846,7 +846,7 @@ describe("Campaign Management", () => {

// Missing templateId
expect(() =>
CreateAndScheduleCampaignParamsSchema.parse({
CreateBlastCampaignParamsSchema.parse({
name: "Test Campaign",
listIds: [456],
sendAt: "2026-03-01 10:00:00",
Expand Down Expand Up @@ -888,7 +888,7 @@ describe("Campaign Management", () => {
});
});

describe("createAndScheduleCampaign", () => {
describe("createBlastCampaign", () => {
it("should call campaigns/create endpoint with blast params", async () => {
const mockResponse = { data: { campaignId: 12345 } };
mockAxiosInstance.post.mockResolvedValue(mockResponse);
Expand All @@ -900,7 +900,7 @@ describe("Campaign Management", () => {
sendAt: "2026-03-01 10:00:00",
};

const result = await client.createAndScheduleCampaign(params);
const result = await client.createBlastCampaign(params);

expect(mockAxiosInstance.post).toHaveBeenCalledWith(
"/api/campaigns/create",
Expand Down
Loading