# Create campaign

### API Description

## Create

> Create a new campaign

```json
{"openapi":"3.1.0","info":{"title":"Batch - REST API","version":"2.9"},"tags":[{"name":"Campaigns"}],"servers":[{"url":"https://api.batch.com/{version}","description":"production","variables":{"version":{"default":"2.10","description":"Version of the API"}}}],"security":[{"rest_key":[]}],"components":{"securitySchemes":{"rest_key":{"type":"http","scheme":"bearer","description":"## API Key Authentication\n\nAuthentication is required in order to interact with Batch's APIs.\n\nBatch implements authentication using API Keys, that we call the \"REST API Key\".\nYou can find it on your dashboard.\n\nPlease make sure that you keep this key secret. You should never use it in client apps to call APIs from there as it would\neasily be extractable.\n\n### How to authenticate\n\nIn order to authenticate your requests, add your REST API Key in the `Authorization` header and prefix it by `Bearer`. Example: `Authorization: Bearer bcd38d9rfb38ra28`.\n"}},"parameters":{"HeaderProjectKey":{"in":"header","name":"X-Batch-Project","description":"The unique project key, identifying a project on the Batch platform","schema":{"type":"string"},"required":true}},"schemas":{"campaign":{"type":"object","required":["name","state","messages","when"],"properties":{"name":{"type":"string","description":"Display name of the campaign on the dashboard"},"state":{"type":"string","enum":["DRAFT","RUNNING","STOPPED"],"description":"State of the campaign to create. Draft campaigns are not sent until they are started (updated to RUNNING). Stopped campaigns are paused and can be resumed by updating them to RUNNING."},"send_rate":{"type":"integer","minimum":1000,"maximum":1000000,"description":"Determines the maximum number of messages to be sent per minute."},"when":{"type":"object","$ref":"#/components/schemas/when","description":"Campaign programation details (when/how to send)"},"targeting":{"type":"object","$ref":"#/components/schemas/targeting","description":"Who should be reached by the campaign"},"labels":{"type":"array","items":{"type":"string"},"description":"An array of labels to assign to the campaign for organizational and capping purposes. Limited at 5 labels per campaign."},"messages":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/email"},{"$ref":"#/components/schemas/push"}],"discriminator":{"propertyName":"channel_type","mapping":{"email":"#/components/schemas/email","push":"#/components/schemas/push"}}},"description":"Messages to send, only one kind of message is allowed at a time."}}},"when":{"type":"object","required":["start_time"],"properties":{"local_time":{"type":"boolean","description":"If true, Batch servers will send messages according to each time zone. The campaign will take 24 hours to complete"},"start_time":{"type":"string","description":"Campaign start date in UTC in a RFC 3339 date-time format (for example 2023-10-24T10:22:00Z) or ***now*** to start the campaign as soon as the call is made"}}},"targeting":{"type":"object","properties":{"languages":{"type":"array","items":{"type":"string"},"description":"An array containing all device languages to be targeted. All language codes in this array must be contained in the messages object. [See here](https://doc.batch.com/api/campaigns/advanced#_language-and-country-codes) for matching rules and valid language codes. E.g.{\"languages\":[\"it\",\"fr\"]}"},"regions":{"type":"array","items":{"type":"string"},"description":"An array containing all the geographical regions codes to be targeted. [See here](https://doc.batch.com/api/campaigns/advanced#_language-and-country-codes) for all valid region codes. E.g.{\"regions\":[\"FR\",\"US\"]}"},"query":{"type":"object","description":"A mongo inspired query object containing filters & operators, based on native attributes (app version, OS version, etc) and custom users data (attributes, tags & events defined by you in the SDK)"}}},"email":{"title":"email","description":"A representation of an email message","type":"object","required":["channel_type","subject","sender_identity_id","html"],"properties":{"channel_type":{"type":"string","enum":["email"]},"subject":{"type":"string","description":"Your email subject. Can use personalization"},"sender_identity_id":{"type":"string"},"reply_to":{"type":"object","required":["email_address"],"properties":{"email_address":{"type":"string"}}},"html":{"type":"string","description":"Your email content as html. Can use personalization"},"languages":{"type":"array","items":{"$ref":"#/components/schemas/languageEmail"},"description":"Array of translations. Default language content is located at the level above."}}},"languageEmail":{"type":"object","required":["language","subject","sender_identity_id","html"],"properties":{"language":{"type":"string"},"subject":{"type":"string","description":"Your email subject. Can use personalization"},"sender_identity_id":{"type":"string"},"reply_to":{"type":"object","required":["email_address"],"properties":{"email_address":{"type":"string"}}},"html":{"type":"string","description":"Your email content as html. Can use personalization"}}},"push":{"title":"push","description":"A representation of a push message","type":"object","required":["channel_type","platform_type","body"],"properties":{"channel_type":{"type":"string","enum":["push"]},"platform_type":{"type":"array","items":{"type":"string","enum":["ios","android","web"]}},"title":{"type":"string","description":"Title of the notification. Can use personalization"},"body":{"type":"string","description":"Body of the notification. Can use personalization"},"media":{"type":"object","description":"Rich notification content","properties":{"picture":{"type":"string","description":"URL to an image that will be displayed as the main notification image. The file must be a RGB PNG or JPG image with a minimum height of 300px and width of 200px. Your server must support the HTTP OPTION verb. Can use personalization"}}},"priority":{"type":"string","enum":["normal","high"],"default":"high","description":"Defines the priority of your message on iOS (APNS) and Android (FCM). If you set `push_type` to `background`, this value MUST be `normal`"},"push_type":{"type":"string","enum":["alert","background"],"default":"alert","description":"Defines whether notifications should show an alert or be silent to trigger a background action"},"time_to_live":{"type":"integer","description":"Time to live (TTL) represents the time a notification can be held for delivery in seconds before expiring. If a user was offline and comes back online after this duration, the notification will not be delivered. It does not remove notifications already delivered to devices. Setting a value of `0` disables the TTL, which leaves expiration up to the platform push service","minimum":0,"maximum":2419200,"default":0},"filter_push_tokens":{"type":"string","enum":["all","collected","imported"],"default":"collected","description":"`all` - the campaign will target imported and collected push tokens<br> `collected` - the campaign will target only collected push tokens, detected by Batch SDKs<br> `imported` - the campaign will target only imported push tokens, not yet detected by Batch SDKs\n"},"ios":{"type":"object","description":"iOS specific attributes","properties":{"deeplink":{"type":"string","maxLength":1024,"description":"Deeplink that the notification should point to once opened. Can use personalization"},"custom_payload":{"type":"string","description":"String representation of a JSON object. Can be used to override standard keys, such as `aps`. Using the `com.batch` key is forbidden. Can use personalization"}}},"android":{"type":"object","description":"Android specific attributes","properties":{"deeplink":{"type":"string","maxLength":1024,"description":"Deeplink that the notification should point to once opened. Can use personalization"},"custom_payload":{"type":"string","description":"String representation of a JSON object. Can be used to override standard keys, such as `aps`. Using the `com.batch` key is forbidden. Can use personalization"},"media":{"type":"object","description":"Rich notification content","properties":{"icon":{"type":"string","description":"URL to an image that will be displayed as the icon of a notification. The file must be a square PNG or JPG image with a minimum size of 196px and your server must support the HTTP OPTION verb. Can use personalization"}}},"collapse_key":{"type":"object","description":"Defines how notifications are managed when an offline device goes online (enabled by default). If enabled, the device will only show the most recent notification. If disabled, it will show all the notifications received when the device was offline. You should disable the collapse key if all your notifications matter (E.g. messages, etc) . You can use up to 3 different collapse keys if you want users to get only one notification of each kind when coming online (E.g. marketing messages, alert, etc)","properties":{"enabled":{"type":"boolean","description":"Whether the collapse_key is enabled or not"},"key":{"type":"string","description":"collapse_key grouping value"}}}}},"web":{"type":"object","description":"Web specific attributes","properties":{"deeplink":{"type":"string","maxLength":1024,"description":"Deeplink that the notification should point to once opened. Can use personalization"},"media":{"type":"object","description":"Rich notification content","properties":{"icon":{"type":"string","description":"URL to an image that will be displayed as the icon of a notification. The file must be a square PNG or JPG image with a minimum size of 196px and your server must support the HTTP OPTION verb. Can use personalization"}}}}},"languages":{"type":"array","items":{"$ref":"#/components/schemas/languagePush"},"description":"Array of translations. Default language content is located at the level above."}}},"languagePush":{"type":"object","required":["language","body"],"properties":{"language":{"type":"string"},"title":{"type":"string","description":"Title of the notification. Can use personalization"},"body":{"type":"string","description":"Body of the notification. Can use personalization"},"media":{"type":"object","description":"Rich notification content","properties":{"picture":{"type":"string","description":"URL to an image that will be displayed as the main notification image. The file must be a RGB PNG or JPG image with a minimum height of 300px and width of 200px. Your server must support the HTTP OPTION verb. Can use personalization"}}},"ios":{"type":"object","description":"iOS specific attributes","properties":{"deeplink":{"type":"string","maxLength":1024,"description":"Deeplink that the notification should point to once opened. Can use personalization"}}},"android":{"type":"object","description":"Android specific attributes","properties":{"deeplink":{"type":"string","maxLength":1024,"description":"Deeplink that the notification should point to once opened. Can use personalization"},"media":{"type":"object","description":"Rich notification content","properties":{"icon":{"type":"string","description":"URL to an image that will be displayed as the icon of a notification. The file must be a square PNG or JPG image with a minimum size of 196px and your server must support the HTTP OPTION verb. Can use personalization"}}}}},"web":{"type":"object","description":"Web specific attributes","properties":{"deeplink":{"type":"string","maxLength":1024,"description":"Deeplink that the notification should point to once opened. Can use personalization"},"media":{"type":"object","description":"Rich notification content","properties":{"icon":{"type":"string","description":"URL to an image that will be displayed as the icon of a notification. The file must be a square PNG or JPG image with a minimum size of 196px and your server must support the HTTP OPTION verb. Can use personalization"}}}}}}},"schemas-SuccessResponse":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"The campaign id associated with the campaign to use for further requests."}}},"Error":{"type":"object","required":["error_message","error_code"],"properties":{"error_message":{"description":"A human readable error message","type":"string"},"error_code":{"description":"Error code","type":"string"}}}},"responses":{"201":{"description":"Request successful, campaign created","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/schemas-SuccessResponse"}]}}}},"400":{"description":"The request is malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The Rest API Key is not valid for this project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unexpected error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Batch's services are under maintenance. Please try again later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/campaigns/create":{"post":{"operationId":"campaigns_create","summary":"Create","description":"Create a new campaign","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/HeaderProjectKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/campaign"}}}},"responses":{"201":{"$ref":"#/components/responses/201"},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"},"503":{"$ref":"#/components/responses/503"}}}}}}
```

### Request structure

Campaign API exposes a POST endpoint that allows to create a campaign:

`/campaigns/create`

#### Headers and authentication

See [Overview → Using Project APIs](https://doc.batch.com/developer/api/cep/..#request-headers-and-authentication).

#### Post data

Exemple of a request body:

```json
  {
    "name": "The campaign name",
    "state": "RUNNING",
    "send_rate" : 100000,
    "labels": ["myLabel1", "myLabel2"],
    "when": {
      "local_time": false,
      "start_time": "now"
    },
    "targeting": {
      "languages": [
        "fr"
      ],
      "regions": [
        "FR"
      ],
      "query": {
        "firstname": {
          "$eq": "Jane"
        }
      }
    },
    "messages": [
      {
        "channel_type": "email",
        "subject": "The campaign subject",
        "sender_identity_id": "4012",
        "reply_to": {
          "email_address": "jane.doe@demobatch.com"
        },
        "html": "The campaign HTML content",
        "languages" : [
          {
            "language" : "en",
            "subject" : "The campaign subject",
            "sender_identity_id" : "4012",
            "reply_to": {
              "email_address": "jane.doe@demobatch.com"
            },
            "html": "The campaign HTML content in english"           
          },
          {
            "language" : "fr",
            "subject" : "le sujet de la campagne",
            "sender_identity_id" : "4034",
            "reply_to": {
              "email_address": "jean.dupont@demobatch.fr"
            },
            "html": "HTML en français"            
          }
        ]
      }
    ]
  }
```

The body must include a valid JSON payload containing the following blocks:

* General information about the campaign.
* "When" part (Required) which indicates when to send the campaign.
* "Targeting" which indicates who will be the recipients of the campaign (default is the entire user base).
* "Messages" part (Required) describing the message to send. Payload will be different if you want to send an email or a push message.

### Campaign general information

Describing name and state of the campaign.

```json
  "name": "The campaign name",
  "state": "RUNNING",
  "send_rate" : 100000,
  "labels": ["myLabel1", "myLabel2"],
```

For the time being, Batch supports the "RUNNING", "STOPPED" and "DRAFT" state for a campaign.

#### Send rate *(optional)*

`Send_rate` sets the maximum sending speed for the campaign. The value must be an integer between 1,000 and 1,000,000, representing the number of **messages sent per minute.** This parameter is optional : if not set, the campaign will be sent at the maximum system speed.

#### Labels (optional)

An array of up to 5 unique label strings. These labels must have already been created via Dashboard, otherwise an error will be thrown.

### When block

Describing when to send the campaign - required.

```json
  "when": {
    "local_time": false,
    "start_time": "now"
  }
```

### Targeting block

Describing who will be reached by the campaign. This block is not required, if you omit it, Batch will consider sending the campaign to the entire user base.

```json
  "targeting": {
    "languages": [
      "fr"
    ],
    "regions": [
      "FR"
    ],
    "query": {
      "firstname": {
        "$eq": "Jane"
      }
    }
  }
```

### Messages block - for email

Describing the messages to send when sending an email campaign - required.

```json
  "messages": [
    {
      "channel_type": "email",
      "subject": "The campaign subject",
      "sender_identity_id": "4012",
      "reply_to": {
        "email_address": "jane.doe@demobatch.com"
      },
      "html": "The campaign HTML content",
      "languages" : [
        {
          "language" : "en",
          "subject" : "The campaign subject",
          "sender_identity_id" : "4012",
          "reply_to": {
            "email_address": "jane.doe@demobatch.com"
          },
          "html": "The campaign HTML content in english"           
        },
        {
          "language" : "fr",
          "subject" : "Le sujet de la campagne",
          "sender_identity_id" : "4034",
          "reply_to": {
            "email_address": "jean.dupont@demobatch.fr"
          },
          "html": "HTML en français"            
        }
      ]
    }
  ]
```

`messages` is an array that can only contain one element.

#### Channel type

value should be `email`

#### Sender Identity

Sender identity describes which sender email will be used. This sender needs to be created before the API Call. If not existing, it will not generate a new ID and the API Call will fail. Sender identity ID can be found on the dashboard (Email channel settings).

#### Languages array

Email messages are available with multi-language

### Messages block - for push

Describing the messages to send when sending a push campaign - required.

```json
  "messages": [
    {
      "channel_type": "push",
      "platform_type" : ["ios","android"],
      "title": "The campaign title",
      "body": "The campaign body",
      "time_to_live": 3600,
      "media": {
        "picture": "https://example.com/"
      },
      "priority": "normal",
      "push_type": "alert",
      "filter_push_tokens" : "collected",
      "ios": {
        "deeplink": "https://example.com/",
        "custom_payload": "{\"tag\":\"wake up push\", \"landing_screen\":\"greeting\"}"
      },
      "android": {
        "deeplink": "https://example.com/",
        "custom_payload": "{\"tag\":\"wake up push\", \"landing_screen\":\"greeting\"}",
        "media": {
          "icon": "https://example.com/"
        },
        "collapse_key": {
          "enabled": true,
          "key": "default"
        }
      },
      "web": {
        "deeplink": "https://example.com/",
        "media": {
          "icon": "https://example.com/"
        }
      }
    }
  ]
```

`messages` is an array that can only contain one element.

#### Channel type

value should be `push`

#### Filter push tokens

`filter_push_tokens` allows you to target collected tokens or imported tokens, or both.

* all : the campaign will target imported and collected push tokens
* collected : the campaign will target only collected push tokens, detected by Batch SDKs
* imported : the campaign will target only imported push tokens, not yet detected by Batch SDKs

#### iOS / Android / Web platorms

A push campaign can send the same message to several platforms, using the `platform_type` Array. You can select one platform only or a combination of 2 or 3 platforms. You can add some platform specific values for a platform by setting them inside of the `ios`, `android` and `web` objects.

#### Languages array

Push messages are available with multi-language

#### iOS specific attributes

The iOS object can specify some attributes:

* deeplink
* custom payload

#### Android specific attributes

The Android object comes with android properties:

* deeplink
* custom payload
* media (icon)
* Collapse key

#### Web specific attributes

The Web object can specify some attributes:

* deeplink
* media (icon)

### Multi-language

`languages` allows you to define many translations. Each item of an array will give you translation of many attributes (content & some parameters) for the designed `language`.

All required parameters at the top level of a message is also required in any given translation.

Email & Push messages can both be translated.

### A/B testing

`variants` allows you to define multiple variants of a campaign directly on the CREATE route. Each item of an array will give you a specific variation of many attributes (content & some parameters). \
\
All required parameters at the top level of a campaign are also required in any given variant.\
\
Email & Push campaigns can both be A/B tested.

A/B testing is only activated upon request. Contact us at <support@batch.com> if you need further information.

#### Responses

#### Success

If the POST to the API endpoint is successful you will receive an HTTP 201 confirmation.

#### Failure

If the POST data does not meet the API requirements you will receive an actionable error message. Contact us at <support@batch.com> if you need further support.

* `AUTHENTICATION_INVALID` (Http status code: 401, Error code: 10)
* `API_MISUSE` (Http status code: 403, Error code: 12)
* `ROUTE_NOT_FOUND` (Http status code: 404, Error code: 20)
* `MISSING_PARAMETER` (Http status code: 400, Error code: 30)
* `MALFORMED_PARAMETER` (Http status code: 400, Error code: 31)
* `MALFORMED_JSON_BODY` (Http status code: 400, Error code: 32)
* `SERVER_ERROR` (Http status code: 500, Error code: 1)
* `MAINTENANCE_ERROR` (Http status code: 503, Error code: 2)
* `TOO_MANY_REQUESTS` (Http status code: 429, Error code: 60)\
  If you get a "too many requests" response, please wait for at least 5 seconds before trying again. Further requests might still return this error.
