Send SMS

Quick start

Using the example below, replace ”API_NYCKEL” with a bearer token that you create in the user portal.

curl -X POST "https://api.ip1sms.com/v2/batches" \
-H "Authorization: Bearer API_NYCKEL" \
-H "Content-Type: application/json" \
-d '{
    "sender": "iP1",
    "recipients": [
        "RECIPIENT-NUMBER"
    ],
    "body": "A nice message sent from iP.1 SMS API"
}'

call

Endpoint: /v2/batches

Methodology: POST

Content-Type: application/json

Example of call data

{ "sender": "iP1", "recipients":[ "456189040623", "175368927054", "392094880589", "568798567631" ], "body": "A very nice message", }

The example above contains the call data with the required fields sender, recipients and body, which is required to send an SMS message. See under the heading Fields for call data for a list of all fields and their descriptions.

Fields for call data

Field nameMandatoryTypeDescription and ConditionsExample
senderYesString A Call will be rejected if sender:
  • Is a number longer than 15 digits
  • Consists of an alphanumeric sender with less than 3 characters or greater than 11 characters (Aa-Zz, 0 - 9, 3 - 11 characters)
  • Not matching regex [0-9A-Za-z]{1,11} or if it does not comply with the E164 standard
A message may not reach the recipient if:
  • The operator carrying the recipient does not support the sender

"sender": "46101606060"
      
recipientsYesArray A Call will be rejected if recipients:
  • is longer than 15 characters
  • contains non digit characters
Phone numbers must be written in the MSISDN format. Each phone number is analyzed and validated, with the result shown as a message status. If this step fails, the message will not be sent.

"recipients":[
  "456189040623",
  "175368927054",
  "392094880589",
  "568798567631"
],
      
recipients - templatingNo, it is not.Nestat Object To use the template system, you must convert your previous recipient array to a dictionary of dictionaries. The top-level key is the recipient's MSISDN (phone number). The second-level key is then searched for in the text and replaced with the second-level value.

"recipients":{
  "456189040623": {
      "sign": "sent by Bob"
  },
  "175368927054": {},
  "392094880589": {},
  "568798567631": {},
  "default":{
      "sign": " sent by iP.1"
  }
}
      
bodyYesString A call will fail if body:
  • Is nullempty or only whitespace
  • is longer than 2000 characters

"body": "A very nice message"

typeNo, it is not.String There are two types: sms and flash.
  • sms is a standard SMS.
  • flash is a message that appears once on the device and then deleted.
The standard type is sms.

"type": "sms"
      
datacodingNo, it is not.String There are two types that are available:
  • gsm: 7-bit character set (160 characters/SMS), limited number of characters.
  • ucs: 2-byte character set (70 characters/SMS), allows all characters (e.g. emoji).
If gsm is set, messages that require ucs (extended characters) to be denied. The default is ucs.

"datacoding": "GSM"
      
.
priorityNo, it is not.Integer Used for messages that need to be delivered quickly. Allowed values are 1 (standard, minimum) and 2 (highest).

Setting priorities 2 The price per SMS increases (10 öre for a Swedish account, €0.01 for an international account).

"priority": 1
      
deliveryWindowsNo, it is not.Array Ability to schedule dispatches during specific time windows (e.g., weekdays 10:00-10:15). You can have multiple windows.

Parsing rules:
  • null in the field opens replaced with current date and time.
  • If closes is null is set to 3 days (72 hours) after opens.
The call is rejected if time windows overlap. If no window is specified, one is automatically created according to the rules above.

"deliveryWindows": [
    {
        "opens": "2025-11-12T17:00:19Z",
        "closes": "2025-11-18T17:00:19Z"
    },
    {
        "opens": "2025-11-20T17:00:19Z",
        "closes": "2025-11-26T17:00:19Z"
    }
],
      
deliveryReportUrlNo, it is not.String If a URL is provided, status updates (delivery reports) will be sent there via POST. The reports are separated by recipient and status.

"deliveryReportUrl": "https://ip1.net"
      
referenceNo, it is not.String Allows the user to set a custom ID or credential.

Restrictions:
  • May consist of a maximum of 40 characters.
  • Must not consist of an empty string or blank.
null is default value.

"reference": "custom-id-123"
      
tagsNo, it is not.string An array of tags used to categorize or sort batches. Enables filtering when listing batches.

"tags: ["marketing", "auth", "admin"],
      

Response

The response to a call consists of a JSON with fields describing the content of the batch.

Example of response data

Below you will find an example of a response to a successful request against the batch endpoint. See under the heading Fields for response data for a detailed description of all fields in the response.

{
    "id": "5bc86b6e85c7209830f96936",
    "sender": "46101606060",
    "body": "Hi my name is {name}",
    "owner": "ip1-XXXXX",
    "direction": "MT",
    "type": "flash",
    "datacoding": "GSM",
    "priority": 1,
    "templated": true,
    "priceSummary": {
        "total": 0.125,
        "currency": "EUR",
        "average": 0.0416
    },
    "messageSummary": {
        "101": {
          "messages": 43,
          "sms": 86
        },
        "102": {
          "messages": 3,
          "sms": 6
        },
        "201": {
          "messages": 142,
          "sms": 284
        }
    },
    "deliveryWindows": [
        {
            "opens": "ISO-8601 string",
            "closes": "ISO-8601 string"
        },
        {
            "opens": "ISO-8601 string",
            "closes": "ISO-8601 string"
        }
    ],
    "status": 112,
    "deliveryReportUrl": "https://api.example.com/sms/deliveryreport",
    "reference": "A client reference",
    "tags": ["marketing", "auth", "etc"],
}

Fields for response data

Field nameTypeDescriptionExample
idString Batch ID.

"id": "5bc86b6e85c7209830f96936"
      
senderString The sender ID used in the messages.

"sender": "46101606060"
      
bodyString The original body, i.e. the message text, which is sent, before templates have been applied, according to the original request.

"body": "A very nice message"

ownerStringThe account number of the SMS account that owns the batch

"owner": "ip1-xxxxx"
      
directionString Tells you if the message sent or received by our system
  • MT An acronym for Mobile Terminated, a message that was sent to a mobile device.
  • MO An acronym for Mobile Originated, a message that was sent from a mobile device.

 "direction": "MT"
      
typeString Describes the type of message.
  • sms is a standard SMS.
  • flash is a message that appears once on the device and then deleted.

"type": "sms"
      
datacodingString Tells you which character set is used for the batch.
  • gsm: 7-bit character set (160 characters/SMS), limited number of characters.
  • ucs: 2-byte character set (70 characters/SMS), allows all characters (e.g. emoji).

"datacoding": "GSM"
      
.
priorityInteger Describes the priority used for the batch.

"priority": 1
      
templatedbooleanIndicates if the batch body (message text) contains templating.
          
"templated": true
          
        
priceSummaryarrayGives a summary of the cost of the batch and the currency that debited the account.
          
"priceSummary": {
    "total": 0.125,
    "currency": "EUR",
    "average": 0.0416
}
          
        
messageSummaryarrayGives a summary of the number of messages in the batch divided into status groups.
          
"messageSummary": {
    "101": {
      "messages": 43,
      "sms": 86
    },
    "102": {
      "messages": 3,
      "sms": 6
    },
    "201": {
      "messages": 142,
      "sms": 284
    }
}
          
        
deliveryWindowsArray Displays the batch time window

"deliveryWindows": [
    {
        "opens": "2025-11-12T17:00:19Z",
        "closes": "2025-11-18T17:00:19Z"
    },
    {
        "opens": "2025-11-20T17:00:19Z",
        "closes": "2025-11-26T17:00:19Z"
    }
],
      
statusIntegerCurrent status of the batch. Derived from the direction and latest status of the batch's messages. Available statuses are as follows:
NameStatus codeComment
Planned101The batch is scheduled to be sent in the future.
Ongoing111The batch is being processed and sent out
Sent112The batch has been sent out
Incoming201The batch contains incoming messages
Canceled203The batch has been canceled and will not be sent

"status": 112
      
deliveryReportUrlString Displays any callback url for receiving delivery reports to external software.

"deliveryReportUrl": "https://ip1.net"
      
referenceString Displays the batch reference if available.

"reference": "custom-id-123"
      
tagsstring shows any tags in the batch.

"tags: ["marketing", "auth", "admin"],
      

Code example

Below you will find a simple code example with authentication and functionality for sending an SMS.

Sending SMS C#

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("https://api.ip1sms.com/v2/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "API Key");

    var sms = new OutgoingSMS()
    {
        Sender = "iP1",
        Recipients = new List() { "46712345678" },
        Body = "Test message rest v2",
    };

    HttpResponseMessage response = await client.PostAsJsonAsync("batches", sms);

    if (response.IsSuccessStatusCode)
    {
        Console.WriteLine("Sent");
    }
    else
    {
        Console.WriteLine("Failed, " + response.StatusCode + ": " + await response.Content.ReadAsStringAsync());
    }
}
    
public class OutgoingSMS
{
    public string Sender { get; set; }
    public List Recipients { get; set; }
    public string Body { get; set; }
}

Sending SMS PHP

$conf = array(
    'password' => 'API key',
    apiUrl' => 'api.ip1sms.com/v2/',
    'method' => 'POST',
    'endpoint' => 'batches',
);

$message = array(
    'sender" => "iP1",
    "recipients" => ["46712345678"],
    "body" => "Test message rest v2",
);

$jsonEncodedMessage = json_encode($message);
// Set up request options
$options = array(
    http" => array(
        'header' => array(
            'Content-Type: application/json',
            'Authorization: Bearer '.$conf['password'],
            'Content-Length: ' . strlen($jsonEncodedMessage)
        ),
        'method' => $conf['method'],
        'content' => $jsonEncodedMessage,
    )
);

$url = 'https://' . $conf["apiUrl"] . $conf['endpoint'];
$context = stream_context_create($options);
// Send the request
$response = file_get_contents($url, false, $context);
// Print the response
echo $response;

Send SMS Visual Basic

Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Net.Http.Json

Module Module1
    Sub Main()
        Dim client As New HttpClient()

        client.BaseAddress = New Uri("https://api.ip1sms.com/v2/")
        client.DefaultRequestHeaders.Accept.Clear()
        client.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
        client.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "API Key")

        Dim sms As New OutgoingSMS()
        sms.Sender = "iP1"
        sms.Recipients = New List(Of String)() From {"46712345678"}
        sms.Body = "Test message rest v2"

        Dim response As HttpResponseMessage = client.PostAsJsonAsync("batches", sms).Result

        If response.IsSuccessStatusCode Then
            Console.WriteLine("Sent")
        Else
            Console.WriteLine("Failed, " & response.StatusCode.ToString() & ": " & response.Content.ReadAsStringAsync().Result)
        End If
    End Sub
End Module

Public Class OutgoingSMS
    Public Property Sender As String
    Public Property Recipients As List(Of String)
    Public Property Body As String
End Class

Troubleshooting

In this section, you will find HTTP error status codes and common errors for individual call fields.

Common error status codes

CodeNameSignificanceClass
400Bad RequestThe server cannot understand the request, often due to invalid syntax (e.g. incorrectly formatted JSON data).client panel
401UnauthorizedThe client must authenticate to access the resource (e.g. an API key or login token is missing).client panel
403ForbiddenThe client has authenticated, but is not authorized to perform the action (e.g. a regular user trying to delete other people's data).client panel
404Not FoundThe server has not found the resource that was requested (e.g. a specific resource with an ID that does not exist).client panel
405Method Not AllowedThe HTTP method used is not allowed for the resource (e.g. trying to POST to a resource that only accepts GET).client panel
409ConflictThe request could not be completed due to a conflict with the current state of the resource (e.g. trying to create a resource that already exists).client panel
500Internal Server ErrorA generic error message indicating that an unexpected condition on the server prevented it from fulfilling the request.Server error
503Service UnavailableThe server is currently unavailable (e.g. overloaded or down for maintenance).Server error

Troubleshooting specific fields

Each incorrect call that triggers an error status code contains a detailed description in the response body. You can extract this text programmatically to get a clearer picture of what went wrong. If you can't read the error in the response body, you can use the list below to troubleshoot your failed call.

sender

  1. Make sure that the additional service "Optional sender" is activated on your account. You can activate "Optional Sender" in the webshop or via one of our online services.
  2. Ensure that the sender is registered on the account in the user portal.
  3. If the sender consists of a number, ensure that the number is no longer than 15 digits.
  4. If an alphanumeric sender is used, ensure that it consists of 3 - 11 characters, Aa - Zz, 0 - 9.

body

  1. Ensure that the message text does not exceed 2000 characters.
  2. Check the text content to rule out inappropriate or regulated content which may trigger blocking services with some operators.

recipients

  1. Make sure that the number you are trying to send to is in the format MSISDN (4612345678), i.e. a number with a country code, without + or double zeros in front.