REST v2
Cuándo elegir REST v2
Elija REST v2 para nuevas integraciones de SMS, especialmente para flujos de trabajo de alto volumen o asíncronos, ya que ofrece seguimiento basado en UUID, patrones de solicitud modernos y las devoluciones de llamada DLR necesarias para una gestión fiable del estado de entrega; elija REST v1 only when you need compatibility with an existing v1 integration.
Descripción general
Nuestra API RESTv2 de Mobile Gateway le permite enviar mensajes SMS.
La diferencia entre REST y REST v2 radica en un enfoque más moderno, diseñado para la escalabilidad y la mensajería asíncrona. DLR callback Se requieren URL para recibir códigos de error.
El uso de HTTPS es obligatorio; todos los intentos de utilizar HTTP en texto plano se redirigirán a HTTPS. Los datos de las solicitudes y respuestas requieren codificación JSON. Solo se requieren los métodos HTTP GET y POST.
Lo que la API puede hacer
- Enviar mensajes SMS a un único dispositivo móvil
- Programar mensajes SMS para su envío posterior
- Realizar el seguimiento de los mensajes enviados mediante identificadores UUID
- Recuperar los detalles de los mensajes enviados
- Recibir devoluciones de llamada (callbacks) para mensajes entrantes (MO)
- Recibir devoluciones de llamada (callbacks) de confirmación de entrega para actualizaciones del estado del mensaje
Cómo funciona
En la práctica, la API sigue un flujo de trabajo sencillo:
- Autenticarse con las credenciales de la API REST v2 de Mobile Gateway.
- Enviar una solicitud JSON para enviar, programar o recuperar un mensaje.
- Almacenar el ID de mensaje (UUID) devuelto por la API.
- Utilizar el UUID para recuperar los detalles del mensaje o conciliar las devoluciones de llamada (callbacks) de confirmación de entrega.
- Configurar las URL de callback para que la aplicación pueda recibir mensajes entrantes y eventos de estado de entrega.
Cuándo utilizar la API REST v2
Utilice REST API v2 cuando su aplicación requiera una integración moderna de SMS mediante HTTPS, con procesamiento asíncrono y seguimiento de mensajes basado en UUID. Es una opción ideal para nuevos sistemas de mensajería transaccional, alertas operativas, envíos programados y flujos de trabajo de alto volumen que requieran conciliar los resultados de entrega mediante callbacks.
Por lo general, se recomienda optar por REST API v2 para nuevas integraciones. REST v1 resulta útil principalmente cuando se mantiene una integración existente que ya depende de endpoints, callbacks o formatos de respuesta propios de la versión v1.
Antes de empezar
Antes de realizar su primera solicitud, confirme lo siguiente:
- Dispone de credenciales para la API REST v2 de Mobile Gateway.
- Su URL de devolución de llamada (callback) de DLR está configurada para eventos de estado de entrega.
- La dirección IP de su servidor está autorizada si la lista blanca de IP está habilitada.
- Los números de móvil tienen formato internacional; por ejemplo,
+1-829-555-1234. - Sus solicitudes utilizan HTTPS y codificación JSON.
Primera ruta de solicitud exitosa
Para la mayoría de las implementaciones, la forma más rápida de validar la conectividad y la configuración es:
- Autenticarse utilizando las credenciales de la API REST v2.
- Enviar una solicitud POST sencilla a
/messagescon los parámetrosdestinationycontent. - Confirmar la respuesta
202 Acceptedy guardar el ID del mensaje (UUID) devuelto. - Recuperar el mensaje mediante
GET /messages?id={message_id}.
Autenticación
Se utiliza autenticación básica HTTP para todas las solicitudes. Si accede a la API sin las credenciales correctas o sin permiso para acceder a ella, recibirá una respuesta HTTP 401.
Las credenciales de su aplicación de puerta de enlace («nombre de la aplicación» y contraseña) están disponibles en la plataforma: https://omni.modicagroup.com/gateway/api_config/restv2
Necesitará un nombre de usuario y una contraseña para obtenerlas.
Si aún no dispone de estos datos, póngase en contacto con support@modicagroup.com.
Direcciones IP autorizadas
Puede incluir las direcciones IP o los rangos de IP de sus servidores en la lista de permitidos utilizando el botón «Add IP Address» (Añadir dirección IP) situado bajo la sección «Authorised IP Addresses» (Direcciones IP autorizadas).
Nota importante: una vez que se haya añadido una o varias direcciones IP o rangos de IP, se rechazarán las conexiones provenientes de cualquier otra dirección IP; cualquier intento de conexión desde una IP que no figure en la lista dará lugar a un error de autenticación.
Base URI
Todo el acceso a la API se realiza a través de HTTPS y desde:
https://api.modicagroup.com/rest/sms/v2
Versiones
La versión de la API REST es actualmente la v2.
Accept: application/json
Especificación OpenAPI
La especificación OpenAPI (Swagger) se puede encontrar en here.
Puede ver ejemplos de código y un desglose de la especificación. here.
Códigos de error
Pueden producirse los siguientes errores:
| Código | Descripción |
|---|---|
| send_failed | No se pudo poner el mensaje en cola debido a un error desconocido. |
| invalid_json | Datos JSON no válidos en el cuerpo de la solicitud |
| missing_attrib | Falta un atributo obligatorio |
| invalid_attrib | Valor de atributo no válido |
| 400 | Marca de tiempo programada no válida (debe cumplir con RFC3339) |
| 422 | Marca de tiempo programada no válida (no debe ser anterior al momento actual) |
Cadenas de fecha
Fecha completa más horas, minutos, segundos y zona horaria.
YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
YYYY = four-digit year
MM = two-digit month (01=January, etc.)
DD = two-digit day of month (01 through 31)
hh = two digits of hour (00 through 23) (am/pm NOT allowed)
mm = two digits of minute (00 through 59)
ss = two digits of second (00 through 59)
s = one or more digits representing a decimal fraction of a second
TZD = time zone designator (Z or +hh:mm or -hh:mm)
Enviando mensajes
SEnvío a un único destino
Para enviar un mensaje MT a un único teléfono móvil, envíe una solicitud POST:
POST /messages
{
"destination": "+6412345678",
"content": "El contenido de tu mensaje SMS con un texto muy largo https://a.urltoshorten.com/thatislongerthanthemaximummessagelength?withparameters=likethisone integrado en el texto"
}
Atributos opcionales:
{
"scheduled": str: 2017-05-05T10:00:00+12:00,
"source": str:short-code,
"reference": str:alt-reference,
"class": str:application-class,
"mask": str:source-mask,
"sms_class": int:0-3,
"expires": str: 2017-05-05T10:00:00+12:00
}
En caso de éxito:
HTTP/1.1 202 Accepted
Content-Type: application/json
{"id":"1e41f423-24cf-4fa2-9a8a-888c30653305","status":"accepted","detail":"+6412345678"}
En caso de error de validación:
HTTP/1.1 400 Bad Request
{
"error": str:error-code
"error-desc": [str:error-desc]
}
{
"error-desc": "Invalid scheduled timestamp (must be less than 60 days)",
"error": "invalid_attrib"
}
Ejemplo de envío de mensaje SMS
Este ejemplo envía un mensaje SMS utilizando la API REST v2.
curl -v \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-u 'gw_username:abcde12345' \
-d '{"destination": "+64211234567", "content": "Hello world!"}' \
https://{apiDomainName}/rest/sms/v2/messages
const credentials = btoa("gw_username:abcde12345");
const response = await fetch("https://{apiDomainName}/rest/sms/v2/messages", {
method: "POST",
headers: {
"Accept": "application/json",
"Authorization": `Basic ${credentials}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
destination: "+64211234567",
content: "Hello world!"
})
});
const result = await response.json();import requests
import json
from base64 import b64encode
uri = 'https://{apiDomainName}/rest/sms/v2/messages'
username = "gw_username"
password = "abcde12345"
# Token de autorización
def basic_auth(username, password):
token = b64encode(f"{username}:{password}".encode('utf-8')).decode("ascii")
return f'Basic {token}'
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization' : basic_auth(username, password)
}
json_payload = json.dumps({
"destination": "+64211234567",
"content": "Hello world!"
})
response = requests.post(uri, headers=headers, data=json_payload)
if response.status_code == 202:
print(response.json())
else:
print("Error:", response.status_code, response.text)<?php
$payload = json_encode([
"destination" => "+64211234567",
"content" => "Hello world!"
]);
$ch = curl_init("https://{apiDomainName}/rest/sms/v2/messages");
curl_setopt($ch, CURLOPT_USERPWD, "gw_username:abcde12345");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Accept: application/json",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
?>
require "json"
require "net/http"
require "uri"
uri = URI("https://{apiDomainName}/rest/sms/v2/messages")
request = Net::HTTP::Post.new(uri)
request.basic_auth("gw_username", "abcde12345")
request["Accept"] = "application/json"
request["Content-Type"] = "application/json"
request.body = {
destination: "+64211234567",
content: "Hello world!"
}.to_json
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
endimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
String token = Base64.getEncoder()
.encodeToString("gw_username:abcde12345".getBytes(StandardCharsets.UTF_8));
String payload = """
{
"destination": "+64211234567",
"content": "Hello world!"
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://{apiDomainName}/rest/sms/v2/messages"))
.header("Accept", "application/json")
.header("Authorization", "Basic " + token)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes("gw_username:abcde12345"));
var request = new HttpRequestMessage(
HttpMethod.Post,
"https://{apiDomainName}/rest/sms/v2/messages");
request.Headers.Accept.ParseAdd("application/json");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", token);
request.Content = new StringContent(
"""{"destination":"+64211234567","content":"Hello world!"}""",
Encoding.UTF8,
"application/json");
var response = await client.SendAsync(request);
var responseBody = await response.Content.ReadAsStringAsync();Output:
{'id': '287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c', 'status': 'accepted', 'detail': '+64211234567'}
Recuperación de un mensaje SMS
Para recuperar un mensaje, envíe una solicitud GET:
GET /messages?id=[str:message-id]
If a match is found:
HTTP/1.1 200 OK
Location: https://api.modicagroup.com/rest/sms/v2/messages?id=[str:message-id]
{
"id": str:message-id,
"source": str:mobile-number|short-code,
"destination": str:mobile-number|short-code,
"content": str:text-message
"status": str:status
}
Additional attributes are added if available:
{
"reference": str:alt-reference,
}
If not found:
HTTP/1.1 404 Not Found
Obtener ejemplo de mensaje SMS
Este ejemplo recupera un mensaje SMS utilizando la API REST v2.
curl -v \
-H 'Accept: application/json' \
-u 'gw_username:abcde12345' \
'https://{apiDomainName}/rest/sms/v2/messages?id=287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c'
const credentials = btoa("gw_username:abcde12345");
const response = await fetch("https://{apiDomainName}/rest/sms/v2/messages?id=287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c", {
method: "GET",
headers: {
"Accept": "application/json",
"Authorization": `Basic ${credentials}`
}
});
const message = await response.json();import requests
import json
from base64 import b64encode
uri = 'https://{apiDomainName}/rest/sms/v2/messages?id=287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c'
username = "gw_username"
password = "abcde12345"
# Token de autorización
def basic_auth(username, password):
token = b64encode(f"{username}:{password}".encode('utf-8')).decode("ascii")
return f'Basic {token}'
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization' : basic_auth(username, password)
}
response = requests.get(uri, headers=headers)
if response.status_code == 200:
print(response.json())
else:
print("Error:", response.status_code, response.text)<?php
$ch = curl_init("https://{apiDomainName}/rest/sms/v2/messages?id=287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c");
curl_setopt($ch, CURLOPT_USERPWD, "gw_username:abcde12345");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Accept: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
?>
require "json"
require "net/http"
require "uri"
uri = URI("https://{apiDomainName}/rest/sms/v2/messages?id=287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c")
request = Net::HTTP::Get.new(uri)
request.basic_auth("gw_username", "abcde12345")
request["Accept"] = "application/json"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
message = JSON.parse(response.body)import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
String token = Base64.getEncoder()
.encodeToString("gw_username:abcde12345".getBytes(StandardCharsets.UTF_8));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://{apiDomainName}/rest/sms/v2/messages?id=287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c"))
.header("Accept", "application/json")
.header("Authorization", "Basic " + token)
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes("gw_username:abcde12345"));
var request = new HttpRequestMessage(
HttpMethod.Get,
"https://{apiDomainName}/rest/sms/v2/messages?id=287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c");
request.Headers.Accept.ParseAdd("application/json");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", token);
var response = await client.SendAsync(request);
var responseBody = await response.Content.ReadAsStringAsync();Output:
{'id': '287c3a15-c9a8-4a14-b6de-e7a3f06b9b0c', source: '202', destination: '+64211234567', 'reference': '', 'content': 'Hello world!', 'status': 'accepted'}
Devolución de llamada MO
Solo recibirás mensajes MO si has configurado una URL de callback para MO en tu API Configuration.
Recomendamos utilizar https:// para tus URL de devolución de llamada.
Cuando se recibe un mensaje MO dirigido a usted, se realiza una solicitud POST a la URL de callback de MO; dicho callback incluirá los detalles del mensaje MO como un objeto JSON en el cuerpo de la solicitud POST.
POST callback-url
{
"id": str($uuid):message-id,
"source": str:mobile-number,
"destination": str:short-code,
"content": str:text-message,
"operator": str:operator-name
}
En caso de que el mensaje sea una respuesta a un mensaje MT, se añade un atributo adicional “reply_to” (solo cuando se utiliza una secuencia numérica y el mensaje MO es una respuesta a un mensaje MT):
{
"reply_to": str:message-id
}
Si el mensaje contiene un campo reply_to y el mensaje MT incluía una referencia, se añadirá un parámetro adicional:
{
"reference": str:reference
}
Si el mensaje del terminal contiene contenido binario, se proporcionará un atributo adicional:
{
"encoding": str:encoding-type
}
Se proporcionará el valor “base64” para los mensajes que contengan datos binarios. El contenido se suministrará codificado en base64; es necesario decodificarlo para obtener los datos originales. NOTA: Los mensajes SMS estándar con contenido en GSM de 7 bits o Unicode no incluirán este parámetro.
Si el mensaje del terminal se envió como un mensaje concatenado (multiparte) y no llegaron todas sus partes, se proporcionarán dos atributos adicionales:
{
"total_parts": int:total-parts,
"received_parts": int:received-parts
}
“total_parts” es la cantidad de partes que componían el mensaje y “received_parts” es cuántas de esas partes llegaron antes de dejar de esperar las restantes. Ambos atributos se proporcionan siempre juntos, y “received_parts” siempre será menor que “total_parts”.
El contenido suministrado es lo que se pudo armar con las partes que sí llegaron, por lo que falta parte del texto que escribió el remitente. Las partes que se perdieron no son necesariamente las últimas, por lo que el contenido puede empezar o terminar a mitad de una oración, o presentar un vacío intermedio. NOTA: Los mensajes que llegaron completos no incluirán estos parámetros, se hayan enviado como mensaje concatenado o no.
Si procesa el contenido como datos estructurados (por ejemplo, JSON), lo más probable es que un mensaje incompleto no se pueda analizar. Estos atributos le permiten distinguir un mensaje incompleto de un contenido que realmente está mal formado.
Devolución de llamada de DLR
Solo recibirá mensajes de estado DLR si ha configurado una URL de devolución de llamada DLR en su API Configuration.
Recomendamos utilizar https:// para las URL de devolución de llamada.
Cuando se recibe un mensaje DLR para usted, se realiza una solicitud POST a la URL de callback de DLR; dicho callback incluirá los detalles del estado del DLR como un objeto JSON en el cuerpo de la solicitud POST.
POST callback-url
{
"message_id": str($uuid):message-id,
"status": str:dlr-status
"detail": str:detail
}
En caso de que el mensaje MT contenga una referencia, se añade un atributo «reference» adicional:
{
"reference": str:alt-reference
}
Estado del mensaje DLR
A continuación se presentan los códigos de estado devueltos en los DLR que admite nuestra pasarela de mensajería.
| Estado | Descripción |
|---|---|
| sent | El mensaje ha sido enviado por el transportista. |
| received | El mensaje ha sido recibido. |
| rejected | El operador rechazó el mensaje. |
| expired | El operador no pudo entregar el mensaje en el plazo especificado; por ejemplo, cuando el teléfono estaba apagado. |
Cannot_Route (Error al enrutar el mensaje)
Un error Cannot_Route (Error al enrutar el mensaje) indica que el Mobile Gateway no puede enrutar tu mensaje. La causa más común es usar la versión incorrecta de la API REST para tu Gateway.
Antes de investigar más a fondo, confirma lo siguiente:
-
Estás utilizando la versión correcta de la API REST (
RESTv1oRESTv2) para tu Gateway. -
El número de móvil de destino es válido y está soportado por tu Gateway.
-
Su Gateway está configurado para enviar mensajes al país de destino. Este error puede ocurrir si el envío de mensajes a ese país no está habilitado en la configuración de su API.
-
La fuente configurada (ID del remitente o número virtual) coincide con la configuración de tu Gateway.
-
La clase de mensaje es válida para la configuración de tu Gateway. Por ejemplo, no envíes un SMS usando una clase de mensaje de correo electrónico u otra clase que tu Gateway no esté configurado para aceptar.
Si el problema persiste después de verificar la configuración de tu Gateway y los parámetros de la solicitud, por favor contacta a <mailto:{{< supportEmail >}}> para obtener más asistencia.
Estado del mensaje omnicanal
A continuación se presentan los códigos de estado que admite nuestra pasarela de mensajes y que pueden visualizarse en los informes de Omni; no todos los operadores admiten la totalidad de estos códigos.
| Estado | Descripción |
|---|---|
| submitted | Mensaje enviado correctamente al operador para su entrega |
| sent | El mensaje ha sido enviado por el transportista |
| received | El mensaje ha sido recibido |
| frozen | Un error transitorio ha bloqueado este mensaje |
| rejected | El operador rechazó el mensaje |
| failed | La entrega del mensaje ha fallado debido a un problema de conectividad del operador |
| dead | Mensaje asesinado por una administradora |
| expired | El operador no pudo entregar el mensaje en el plazo especificado; por ejemplo, cuando el teléfono estaba apagado. |