# Schedule an SMS using Infobip API

As an outcome of this tutorial, you will be able to schedule an SMS and receive it within the specified time window on to your handset using Infobip SMS API. You'll also learn how to:

* reschedule a scheduled SMS
* change a status of a scheduled SMS
* cancel a scheduled SMS

## Prerequisites

1. [Infobip account](https://portal.infobip.com/login/?callback=https%3A%2F%2Fportal.infobip.com%2F). If you do not have one, you can create a [free trial account](https://www.infobip.com/signup).
2. Infobip API key with `sms:message:send` scope. You can find out more about how to create an API key with the correct scope [here](https://www.infobip.com/docs/essentials/api-essentials/api-authorization).
3. Your favorite HTTP client. In this example, we will use `curl`. Additionally, you can choose the official [Infobip SDK](https://www.infobip.com/docs/sdk) for your preferred programming language.
4. Your sender. If you are in the free trial period, you can use Infobip's test sender, `ServiceSMS`
   If you want to configure your custom sender, request a new number or an alphanumeric sender through the [Infobip account](https://portal.infobip.com/channels-and-numbers/channels/sms/overview) or using [Infobip Numbers API](https://www.infobip.com/docs/api/platform/numbers).
5. Destination - a phone number to which the message will be sent. If you are in the free trial period, you can only send messages to your verified phone number.

## Schedule an SMS

Use the [Send SMS message](https://www.infobip.com/docs/api/channels/sms/outbound-sms/send-sms-messages) to schedule an SMS. You'll use the `sendAt` field to pass in a date on which you want the SMS to arrive.

Key points about scheduling:

* Use the following format: `yyyy-MM-dd'T'HH:mm:ss.SSSZ` within the `sendAt` field to pass the date and time.
* Your message cannot be scheduled later than 180 days in advance.
* Add a`bulkId` field to pass your custom bulk ID which you will then use to manage your scheduled messages. Otherwise, Infobip platform will autogenerate it for you and return it in a response.

```bash
curl -L -g 'https://{baseUrl}/sms/3/messages' \
-H 'Authorization: {authorization}' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
  "messages": [
    {
      "sender": "InfoSMS",
      "destinations": [
        {
          "to": "447415774332"
        }
      ],
      "content": {
        "text": "Our summer collection is ready, check it out!"
        }
      }
  ],
  "options": {
    "schedule": {
      "bulkId": "summer-campaign",
      "sendAt": "2025-05-19T11:15:00.000+0000"
    }
  }
}'
```

### Assign a delivery time window

This is an optional step which you can skip.

Sometimes, you may have to comply to certain rules and may want to stick to a clearly defined time period outside of which your messages won't get sent to your users. Use the `deliveryTimeWindow` to set up the exact days and the exact time of the day to start and stop sending messages.

NOTE
It's not recommended to create multiple messages with different `deliveryTimeWindow` under a single bulk, as it may affect searching for messages, rescheduling, canceling, or updating them.

```bash
{
  "messages": [
    {
      "sender": "InfoSMS",
      "destinations": [
        {
          "to": "41793026700"
        }
      ],
      "content": {
        "text": "Our summer collection is ready, check it out!"
      },
      "options": {
        "deliveryTimeWindow": {
          "days": [
            "MONDAY",
            "TUESDAY",
            "WEDNESDAY",
            "THURSDAY",
            "FRIDAY"
          ],
          "from": {
            "hour": 9,
            "minute": 0
          },
          "to": {
            "hour": 20,
            "minute": 0
          }
        }
      }
    }
  ],
  "options": {
    "schedule": {
      "bulkId": "summer-campaign",
      "sendAt": "2025-05-21T09:00:00.000+0000"
    }
  }
}
```

## Get a response

Once you run the code, you should see a `200 OK` response and receive an SMS at the specified date and time. The response contains a `bulkId` that you can use to manage your scheduling, e.g. reschedule your message, view/update its status, or cancel it completely. You can also use it for analytics and troubleshooting.

```bash
{
  "bulkId": "summer-campaign",
  "messages": [{
      "messageId": "35841637745505282710",
      "status": {
        "description": "Message sent to next instance",
        "groupId": 1,
        "groupName": "PENDING",
        "id": 26,
        "name": "MESSAGE_ACCEPTED"
      },
      "to": "2250be2d4219-3af1-78856-aabe-1362af1edfd2"
    }]
}
```

## Reschedule an SMS

To reschedule your SMS use bulkId to identify which message you want to reschedule and pass it as a query parameter The body should only contain the `sendAt` field with a new date and time you want to use Note that, just like with scheduling, the new date cannot exceed 180 days into the future.

```bash
curl -L -g -X PUT 'https://{baseUrl}/sms/1/bulks?bulkId=summer-campaign' \
-H 'Authorization: {authorization}' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
  "sendAt": "2025-06-01T14:27:00.000+0000"
}'
```

If successful, you'll get a `200 OK` response that returns the new date and confirms the bulk ID.

```bash
{
"bulkId": "summer-campaign",
"sendAt": "2025-06-01T14:27:00.000+0000"
}
```

## View the status of your scheduled messages

To view the status of your scheduled message you'll again need to know your bulk ID and pass it in as a query parameter.

```bash
curl -L -g 'https://{baseUrl}/sms/1/bulks/status?bulkId=summer-campaign' \
-H 'Authorization: {authorization}' \
-H 'Accept: application/json'
```

The `200 OK` response will contain the confirmation of the bulk ID and the current status of your message.

```bash
{
  "bulkId": "summer-campaign",
  "status": "PENDING"
}
```

## Cancel the scheduled SMS or change its status

You can cancel the scheduled SMS or update its status by passing in your bulk ID as a query parameter and the status you wish to update it with in the request body.

```bash
curl -L -g -X PUT 'https://{baseUrl}/sms/1/bulks/status?bulkId=summer-campaign' \
-H 'Authorization: {authorization}' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
  "status": "CANCELED"
}'
```

Your `200 OK` response will confirm the bulk ID and the new status of the message In the case of a `CANCELED` status, the sending of the message will also get canceled.

```bash
{
  "bulkId": "summer-campaign",
  "status": "CANCELED"
}
```

## Analytics and troubleshooting

For troubleshooting and analytics, use the auto-generated `messageId` or your `bulkId` to view the message and its details by fetching a Delivery Report.