API authentication
All API requests need to be authenticated through the Authorization header. The Infobip API offers the following authentication methods:
- HTTP Basic authentication
- API Keys
- IBSSO Tokens
- OAuth 2.0
Select your preferred method to suit your current tech stack and security requirement level. Many of these methods are vulnerable to man-in-the-middle attacks, so it is recommended to combine them with other security mechanisms such as an encrypted connection or SSL.
Refer to the Errors section to troubleshoot potential issues, or alternatively reach out to the Infobip Support team for help.
Basic
Basic authentication works by sending a username and password in every API request. Typically, this method is used in situations when the API key is not available. For example, API methods generating API keys could be authenticated with Basic.
Basic authentication is the least recommended method as it is still simple to decode encrypted credentials back to their original values. Please refer to the HTTP Authentication resource to see how to restrict access to your server with Basic authentication.
Here are some key facts about this method:
- Built into HTTP protocol itself
- Credentials should be encoded in a Base64 format (e.g. with the RFC2045-MIME variant) and separated by a colon :
- Encoded credentials are added to the header after "
Basic
"
Example - HTTP client
When using any of the Infobip API client libraries you don't have to manually encode the credentials. You only need to specify the username and password when creating an instance of a client object.
curl -L -g -X GET 'https://{baseUrl}/sms/2/text/advanced' /
-H 'Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
String auth = username + ":" + password;
String encoded = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8"));
String messageText = "This is test message sent using OkHttpClient and Basic auth";
String jsonBody = String.format(
"{\"messages\":[{\"from\":\"%s\",\"destinations\":[{\"to\":\"%s\"}],\"text\":\"%s\"}]}",
SENDER, PHONE_NUMBER, messageText);
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonBody);
Request request = new Request.Builder()
.url(BASE_URL + "/sms/2/text/advanced")
.addHeader("Authorization", "Basic " + encoded)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Response response = httpClient.newCall(request).execute();
System.out.println(response.body().string());
string username = "USERNAME";
string password = "PASSWORD";
string concatenated = $":{password}";
string encoded = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(concatenated));
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encoded);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Example - API client library
When using any of the Infobip API client libraries you do not have to manually encode the credentials data like mentioned above. You only need to specify the username and password when creating an instance of a client object as shown in the example below.
var configuration = new Configuration()
{
BasePath = "BASE_URL",
Username = "USERNAME",
Password = "PASSWORD"
};
API key header
An API key is an access token that a client provides when making API calls. It's a simple way to secure access and thus the most popular authentication method used with REST APIs. The key can be sent in the query string or as a request header. You are automatically assigned an API Key once you create an account. Generate more keys and manage the existing ones through the Infobip API key management page.
Here are some key facts about this method:
-
API keys can be generated by calling the dedicated API method
-
Keys can be revoked at any time which is useful when separating the API access rights across multiple applications or use cases
-
Lost API keys are easily retrievable
- Infobip API keys have a predefined expiry date to eventually become invalid
Example - HTTP client
The examples below show how to specify the API Key authentication when using client libraries.
curl -L -g -X GET 'https://{baseUrl}/sms/2/text/advanced' /
-H 'Authorization: App 003026abc133714df1834b8638bb496e-8f4b3d9a-e931-478d-a994-28a725159ab9'
Request request = new Request.Builder()
.url("BASE_URL" + "/sms/2/text/advanced")
.addHeader("Authorization", "App " + apiKey)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("App", "API_KEY");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Example - API client library
The examples below show how to prepare an HTTP request using API Key authentication. Note this request is much simpler than using a basic authentication request.
ApiClient apiClient = ApiClient.forApiKey(ApiKey.from(API_KEY))
.withBaseUrl(BaseUrl.from(BASE_URL))
.build();
var configuration = new Configuration()
{
BasePath = "BASE_URL",
ApiKeyPrefix = "App",
ApiKey = "API_KEY"
};
IBSSO token header
IBSSO tokens are session-based meaning tokens are valid for a short amount of time. That ultimately makes this method more secure, but also requires more maintenance to keep authentication valid.
Typically, this kind of authentication is used in single sign-on scenarios where multiple sign-ins which to be avoided across the system. It may be also useful in scenarios when sensitive data needs to be handled centrally without the need to distribute it across various enterprise systems.
Here are some key facts about this method:
- All API requests are authenticated with a session token.
- By default, IBSSO tokens will expire after 60 minutes after which a new token must be created.
- If you want to create a new token but the previous one has not expired yet, you will first need to destroy the session.
- You can shorten the session's length with a dedicated API call.
How to use IBSSO tokens
- Make a call to create a session endpoint and take the token from the response.
- Include
"IBSSO"
and the token in the Authorization header for all subsequent calls.
Authorization: IBSSO 2f9b4d31-2d0d-49a8-85f0-9b862bdca394
- Optionally, destroy the session to adjust the session's length to your needs. By default, the session will expire after 60 minutes.
HTTP request
Obtain IBSSO token
Create a session by calling the Create session endpoint. The response will contain the token which can then be used in the HTTP header of the requests to other API endpoints such as Send SMS.
private static class IbssoResponse {
public IbssoResponse() {
super();
}
@JsonProperty("token")
public String token;
@JsonGetter("token")
public String getToken() {
return token;
}
@JsonSetter("token")
public void setToken(String token) {
this.token = token;
}
}
String jsonBody = String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "USERNAME", "PASSWORD");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonBody);
Request request = new Request.Builder()
.url("BASE_URL" + "/auth/1/session")
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Response response = httpClient.newCall(request).execute();
String responseBody = response.body().string();
System.out.println(responseBody);
IbssoResponse ibssoResponse = new ObjectMapper().readValue(responseBody, IbssoResponse.class);
return ibssoResponse.token;
public class IbssoResponse
{
[System.Text.Json.Serialization.JsonPropertyName("token")]
public string Token { get; set; }
}
string username = "USERNAME";
string password = "PASSWORD";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string body = $@"
{{
""username"": """",
""password"": ""{password}""
}}";
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, "/auth/1/session");
httpRequest.Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json");
var response = client.SendAsync(httpRequest).GetAwaiter().GetResult();
var responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var responseObject = JsonSerializer.Deserialize(responseContent);
return responseObject.Token;
Example - HTTP client
The examples below show how to prepare the HTTP request. Note that this is almost identical to API Key authentication, but instead of App
, you will use IBBSO
in the header.
private static class IbssoResponse {
public IbssoResponse() {
super();
}
@JsonProperty("token")
public String token;
@JsonGetter("token")
public String getToken() {
return token;
}
@JsonSetter("token")
public void setToken(String token) {
this.token = token;
}
}
String jsonBody = String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "USERNAME", "PASSWORD");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonBody);
Request request = new Request.Builder()
.url("BASE_URL" + "/auth/1/session")
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Response response = httpClient.newCall(request).execute();
String responseBody = response.body().string();
System.out.println(responseBody);
IbssoResponse ibssoResponse = new ObjectMapper().readValue(responseBody, IbssoResponse.class);
return ibssoResponse.token;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("IBSSO", "TOKEN");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Example - API library
When using any of the Infobip API client libraries, you will need the same elements that you would for the API Key authentication, but instead of App
, you will use IBBSO.
var configuration = new Configuration()
{
BasePath = "BASE_URL",
ApiKeyPrefix = "IBSSO",
ApiKey = "TOKEN"
};
OAuth 2.0
This type of authentication is the most secure option and is almost industry standard. Similar to using IBSSO tokens, you will use an access token you get from separate endpoint.
Here are some key facts about this method:
- The access token returned in response will expire within the time limit provided in seconds in the same response.
- Infobip acts as both a resource and an authorization server.
- A new token has to be created once the token expires - There is no automatic token retrieval.
For more details, see the official OAuth 2.0 specification.
How to use OAuth 2.0
- Make a call to get the access token and the expiration time from a separate endpoint.
- Include
"Bearer "
and the token in the Authorization header for all subsequent calls until the token expires.
Authorization: Bearer eyJraWQiOiI5d29rWGRoSSIsInR5cCI6IkpXVCIsImFsZyI6IkhTMjU2In0.eyJzdWIiOiJERDIwMjAiLCJpc3MiOiJpbmZvYmlwLmNvbSIsImV4cCI6MTYzMzAwNDQwNiwiaWF0IjoxNjMzMDAwODA2LCJqdGkiOiJiMmJmODgyMS01OTcxLTRiOTMtYWVmNy0zM2QwMDNkMjIxNjcifQ.KvIIOmCKJETiB6xKOqBxvZYnYOa8RAulYhChBEmI4Os
HTTP request
Obtain OAuth token
Similarly to IBSSO tokens, you have to first obtain a token before making any API calls.
private static class OauthResponse {
public OauthResponse() {
super();
}
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("expires_in")
private String expiresIn;
@JsonGetter("access_token")
public String getAccessToken() {
return accessToken;
}
@JsonSetter("access_token")
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
@JsonGetter("expires_in")
public String getExpiresIn() {
return expiresIn;
}
@JsonSetter("expires_in")
public void setExpiresIn(String expiresIn) {
this.expiresIn = expiresIn;
}
}
HttpPost post = new HttpPost(BASE_URL + "/auth/1/oauth2/token");
List nvps = new ArrayList();
nvps.add(new BasicNameValuePair("client_id", username));
nvps.add(new BasicNameValuePair("client_secret", password));
nvps.add(new BasicNameValuePair("grant_type", "client_credentials"));
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(post);
System.out.println(response.getStatusLine());
String responseJson = EntityUtils.toString(response.getEntity());
System.out.println(responseJson);
OauthResponse oauthResponse = new ObjectMapper().readValue(responseJson, OauthResponse.class);
return oauthResponse.accessToken;
public class OauthResponse
{
[System.Text.Json.Serialization.JsonPropertyName("expires_in")]
public int ExpiresIn { get; set; }
[System.Text.Json.Serialization.JsonPropertyName("access_token")]
public string AccessToken { get; set; }
}
string username = "USERNAME";
string password = "PASSWORD";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
var dict = new Dictionary();
dict.Add("client_id", username);
dict.Add("client_secret", password);
dict.Add("grant_type", "client_credentials");
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, "/auth/1/oauth2/token");
httpRequest.Content = new FormUrlEncodedContent(dict);
var response = client.SendAsync(httpRequest).GetAwaiter().GetResult();
var responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var responseObject = JsonSerializer.Deserialize(responseContent);
var accessToken = responseObject.AccessToken;
Example - HTTP client
The examples below show how to prepare an HTTP client request with a header.
Request request = new Request.Builder()
.url("BASE_URL" + "/sms/2/text/advanced")
.addHeader("Authorization", "Bearer " + accessToken)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(body)
.build();
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "ACCESS_TOKEN");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Example - API library
The examples below show how to prepare an HTTP request with headers.
var configuration = new Configuration()
{
BasePath = "BASE_URL",
ApiKeyPrefix = "Bearer",
ApiKey = "ACCESS_TOKEN"
};
API scopes
IMPORTANT
The rollout for this feature is scheduled to start on February 28, 2024, specifically for API keys.
A scope has become a standard term in the API environment. It originated in OAuth2 specification, and the same idea is applied to all authentication types. It is an additional layer of control and security over the REST API that limits what the end-point users, API key, or OAuth clients are allowed to call.
Scopes provide access to a specific set of API endpoints, typically designed to serve specific use cases. Through OAuth2, they define the specific actions that applications are permitted to do on behalf of a user.
By granting a specific API scope to a user or an API key, you limit their access to a subset of API endpoints covered by the scope. In this way, you can prevent the user from accessing data or API functionalities outside of their role. You can limit the potential negative impact of leaked or stolen API keys or user credentials. You can grant several scopes to the same user or API key, covering multiple different API endpoints needed for a complex use case.
API scope types
Various scope types exist depending on the area or context. The main scopes include:
- General:
- message:send
- Enables sending of mobile terminated (MT) messages, regardless of the channel
- Includes all channel:message:send endpoints (all channels)
- inbound-message:read
- Enables fetching of mobile originated (MO) messages, regardless of the channel
- Includes all channel:inbound-message:read endpoints (all channels)
- web:sdk - Provides access to the mobile app messaging API endpoints accessed from the client-side SDK
- mobile-app-messaging:sdk - Provides access to people and people events API endpoints accessed from client-side SDK
- message:send
- product/channel:manage - Includes all endpoints related to a specific product or channel; e.g., if it is a Conversations product, it includes all endpoints related to Conversations; if it is an SMS channel, it includes all endpoints related to SMS
Additionally, there are other scope types that vary depending on the channel, product, and different use cases. You can review all available scopes on the Create API key page.
API scope configuration
To configure API scope(s), you will need to allow the API key to access each API endpoint you want to use. To do that, first check the documentation of the API endpoint. It will list the required scopes. Granting any of them will enable the API key to access the endpoint.
You can grant new scopes to an existing API key by editing it or create a new one with scopes from the beginning.
You can manage API keys either through dedicated API, or through the web interface.
If you want to configure the API scope(s) through the web interface, navigate to Developer Tools → API Keys → Create API key.
From there, enter the following information for the API key:
- Name
- Creation date
- Expiration date
- Allowed IP addresses (optional)
In the next section, API scopes, choose which scopes you want to include:
- General
- Channels
- Connectivity
- Platform
- Customer Engagement
- Web SDK
Upon selecting a specific scope option, a drop-down menu will appear containing all available scopes. From there, you are required to choose which scopes you want to include in the API key.
Errors
Commonly you will get the 401 Unauthorised
HTTP status code in response when there is a missing or invalid username or password.
{
"requestError": {
"serviceException": {
"messageId": "UNAUTHORIZED",
"text": "Invalid login details"
}
}
}
Library exceptions
When using one of the libraries, make sure to handle API exceptions.
try {
SmsResponse smsResponse = sendSmsApi.sendSmsMessage(smsMessageRequest);
} catch (ApiException apiException) {
apiException.getCode();
apiException.getResponseHeaders();
apiException.getResponseBody();
}
try
{
var result = api.SendSmsMessage(smsRequest);
}
catch(ApiException apiException)
{
var errorCode = apiException.ErrorCode;
var errorContent = apiException.ErrorContent;
}