Agentic - Campaigns

Create a new AI-powered outbound campaign

Changed on

Create a new campaign for automated outbound calling with AI agents. Campaigns allow you to:

  • Automate outbound calls to a list of leads with AI agents
  • Schedule campaigns to run at specific times and days
  • Configure retry logic for failed or unanswered calls
  • Manage concurrent calls to control call volume
  • Track campaign performance with real-time statistics

Required Fields:

  • name: Descriptive name for the campaign

Call source:

  • sipTrunkIds: SIP trunks to dial out from (get from POST /phones/sip-trunks/query). Required to go live unless verifiedCallerId is set. Drafts may omit this and finish setup later.
  • agentId: AI agent that handles the calls (company default if omitted)

Optional Configuration:

  • schedule: Business hours, timezone, and how often to pick pending leads
  • retries: Call-backs after the first call when nobody answers (busy, voicemail, no answer, or failed to connect) (0-10, default 3; a lead gets at most retries + 1 calls)
  • retryDelayMinutes: Minutes between those calls (default 240 = 4 hours; the app offers 60 to 40320 = 1 hour to 4 weeks)
  • maximumConcurrentCalls: Limit concurrent calls (max 100)
  • defaultCallerIds: Pool of caller IDs presented to leads
  • notificationSettings: Email notifications for campaign events

After creating a campaign, add leads with POST /agentic/campaign-leads, then set status to "active" (or use resume) to start calling.

Human seats (optional): set userSettings.userIds so users can dial the autogenerated extensionNumber and stay parked. dispatchStrategy (random | least_answered | round_robin) picks who gets the next lead. Outbound leads are dialed only while at least one assigned user is online (Windows app connected, or parked on the campaign extension). overflowToAi (default true) is only for a live lead that cannot attach to an online user — AI instead of hold music. Hangup after a lead does not leave the campaign — POST /:id/disconnect does.

post/api/v1/agentic/campaigns

Request

  • Base URL: https://api.voicelogica.ai
  • URL: https://api.voicelogica.ai/api/v1/agentic/campaigns
  • Auth: API key in header x-api-key

Headers

x-api-keystring required

Your API key for authentication. Required for all endpoints.

x-company-idstring

Optional company ID for resellers. When provided, the API request will operate on behalf of the specified subsidiary company. The API key must have access to the specified company.

Request body

namestring required

Name of the campaign

descriptionstring

Description of the campaign purpose and goals

type'email' | 'phone' | 'sms'

Primary channel type for the campaign

purpose'appointment' | 'lead_qualification' | 'event_invite' | 'payment_collection' | 'custom'

What the campaign is trying to achieve. Non-custom purposes seed campaign-level analysis fields and call instructions; "custom" (default) leaves everything as-is

promptSectionstring

Campaign call instructions injected into the agent context at the start of every campaign call

appointmentServiceKeysstring[]

Appointment campaigns only: the agent services (serviceKey, from appointmentSettings.services) this campaign books. Left empty, a lead counts as already booked when ANY upcoming calendar event carries their phone number or email. With services picked, the event must ALSO name one of them — an upcoming event with only the phone number means a different service, so the lead is still called. Ignored for other goals.

dynamicWelcomeMessageboolean

When true, campaign calls open with an AI-generated greeting built from the campaign goal and lead context instead of the agent's fixed welcome message. Explicit opt-in: each call is then billed with a minimum duration of 10 seconds, even if it ends unanswered

welcomeMessagestring

Static opening spoken on every campaign call. Used only when dynamicWelcomeMessage is not true. Empty means the agent welcome

acceptDynamicVariablesboolean

When true (default if omitted), extra columns on a lead list become dynamicVariables automatically. When false, only leadColumns (plus phone) are accepted as extra lead fields

status'draft' | 'active' | 'paused' | 'completed'

Current status of the campaign

retriesinteger

Number of retries for the campaign (0-10; defaults to 3)

maximumConcurrentCallsnumber

Maximum number of concurrent calls for the campaign (max 100)

retryDelayMinutesinteger

Delay between retry attempts in minutes (60-40320; defaults to 240 = 4 hours)

agentIdstring

ID of the agent responsible for the campaign

sipTrunkIdsstring[]

SIP trunks to dial out from. Get IDs from POST /phones/sip-trunks/query. Required to go live unless verifiedCallerId is set.

verifiedCallerIdstring

Verified phone number used as caller ID when dialing on the company trunk

defaultCallerIdsstring[]

Pool of numbers presented to the people being called, for every lead that does not carry its own callerId. Each entry must be a number the campaign SIP trunks own (the trunk default number or an inbound trunk number / DID). One entry = every lead sees that number; several = the pool is spread across leads, each lead keeping the same number across its retries. Empty = the trunk decides, as before

lastRunAtstring date-time

ISO 8601 date string

allowedPhoneNumbersstring[]

Array of phone numbers that are allowed to be called

defaultCampaignboolean

Whether this is the default campaign for the company

processingNowboolean

Whether the campaign is currently being processed by the job service

processingNowSincestring date-time

ISO 8601 date string

Example request

{
  "name": "Q4 Sales Campaign",
  "description": "Outbound sales campaign for Q4 revenue generation",
  "type": "phone",
  "status": "draft",
  "agentId": "507f1f77bcf86cd799439012",
  "sipTrunkIds": [
    "507f1f77bcf86cd799439011"
  ],
  "retries": 3,
  "retryDelayMinutes": 240,
  "maximumConcurrentCalls": 5,
  "schedule": {
    "days": [
      {
        "day": "monday",
        "runFromTime": {
          "hours": 9,
          "minutes": 0
        },
        "runToTime": {
          "hours": 17,
          "minutes": 0
        }
      },
      {
        "day": "tuesday",
        "runFromTime": {
          "hours": 9,
          "minutes": 0
        },
        "runToTime": {
          "hours": 17,
          "minutes": 0
        }
      }
    ],
    "timeZone": "Europe/Athens",
    "runEverySeconds": 60
  }
}

Response

Campaign created successfully

idstring required

Unique identifier

createdAtstring date-time required

Creation timestamp

activeboolean required

Whether the entity is active

createdBystring required

Name of the user who created the entity

createdByIdstring required

ID of the user who created the entity

modifiedAtstring date-time

ISO 8601 date string

modifiedBystring

Name of the user who last modified the entity

modifiedByIdstring

ID of the user who last modified the entity

companyIdstring required

Company identifier

companyobject

Any valid JSON value

groupIdsstring[]

Linked group IDs

namestring required

Name of the campaign

descriptionstring

Description of the campaign purpose and goals

type'email' | 'phone' | 'sms'

Primary channel type for the campaign

purpose'appointment' | 'lead_qualification' | 'event_invite' | 'payment_collection' | 'custom'

What the campaign is trying to achieve. Non-custom purposes seed campaign-level analysis fields and call instructions; "custom" (default) leaves everything as-is

promptSectionstring

Campaign call instructions injected into the agent context at the start of every campaign call

appointmentServiceKeysstring[]

Appointment campaigns only: the agent services (serviceKey, from appointmentSettings.services) this campaign books. Left empty, a lead counts as already booked when ANY upcoming calendar event carries their phone number or email. With services picked, the event must ALSO name one of them — an upcoming event with only the phone number means a different service, so the lead is still called. Ignored for other goals.

dynamicWelcomeMessageboolean

When true, campaign calls open with an AI-generated greeting built from the campaign goal and lead context instead of the agent's fixed welcome message. Explicit opt-in: each call is then billed with a minimum duration of 10 seconds, even if it ends unanswered

welcomeMessagestring

Static opening spoken on every campaign call. Used only when dynamicWelcomeMessage is not true. Empty means the agent welcome

acceptDynamicVariablesboolean

When true (default if omitted), extra columns on a lead list become dynamicVariables automatically. When false, only leadColumns (plus phone) are accepted as extra lead fields

status'draft' | 'active' | 'paused' | 'completed'

Current status of the campaign

retriesinteger

Number of retries for the campaign (0-10; defaults to 3)

maximumConcurrentCallsnumber

Maximum number of concurrent calls for the campaign (max 100)

retryDelayMinutesinteger

Delay between retry attempts in minutes (60-40320; defaults to 240 = 4 hours)

agentIdstring

ID of the agent responsible for the campaign

voipPhoneIdsstring[]

Legacy VoIP phone IDs. Prefer sipTrunkIds.

sipTrunkIdsstring[]

SIP trunks to dial out from. Get IDs from POST /phones/sip-trunks/query. Required to go live unless verifiedCallerId is set.

verifiedCallerIdstring

Verified phone number used as caller ID when dialing on the company trunk

defaultCallerIdsstring[]

Pool of numbers presented to the people being called, for leads without their own callerId

lastRunAtstring date-time

ISO 8601 date string

allowedPhoneNumbersstring[]

Array of phone numbers that are allowed to be called

defaultCampaignboolean

Whether this is the default campaign for the company

processingNowboolean

Whether the campaign is currently being processed by the job service

processingNowSincestring date-time

ISO 8601 date string

extensionNumberstring

Autogenerated 2–3 digit extension users dial to join the campaign

Example response

{
  "id": "123",
  "companyId": "123",
  "name": "Q4 Sales Campaign",
  "description": "Outbound sales campaign for Q4 revenue generation",
  "type": "phone",
  "status": "active",
  "retries": 3,
  "retryDelayMinutes": 30,
  "maximumConcurrentCalls": 10,
  "notificationSettings": {
    "enabled": true,
    "emails": [
      "test@example.com"
    ],
    "sendAtHour": 10
  }
}

Changes

    • breaking

      the request property type changed from number to integer

    • breaking

      the request property type changed from number to integer

    • warning

      the request property's max was set to 40320.00

    • warning

      the request property's min was set to 60.00