Planes de integración para IA

Descarga un plan en Markdown y entrégalo a tu asistente de programación junto con el contexto de tu proyecto. Nunca pegues tu API Key en el prompt: configúrala como secreto en tu entorno.

Plan v2 · recomendado Plan v1 · compatible

Introducción

La API de EnvíaTuSMS permite a los desarrolladores el envío programático de mensajes de texto (SMS) de forma individual y masiva haciendo uso de su balance. Las peticiones pueden realizarse de forma secuencial o asíncrona según sea el requerimiento.

Las peticiones realizadas a la API podrán realizarse utilizando la librería cURL con el lenguaje de programación de su preferencia.
Las peticiones GET reciben los parametros en la URL.
Las peticiones POST reciben los parametos codificados en JSON con un header Content-Type: application/json.
Las respuestas retornadas por la API serán en formato JSON.

Una petición exitosa retornará un estatus HTTP de 200 OK.

API URL

URL principal para todas las peticiones.

https://www.enviatusms.com/api/v1 (también disponible en https://www.enviatusms.com/api para clientes existentes; los ejemplos tradicionales que usan esta última ruta siguen siendo válidos)

Autenticación

Todas las peticiones deberán estar acompañadas de su api_key como parámetro GET en la URL, la cual puede verificar accediendo desde su cuenta aquí.

Desde las opciones de su cuenta puede regenerar la API Key o limitar su uso a direcciones IPv4 o IPv6 específicas (una por línea). Si no indica ninguna IP, se permiten peticiones desde cualquier dirección. Al regenerar la clave, la anterior deja de funcionar.

Ejemplo de petición con autenticación

https://www.enviatusms.com/api/v1/balance?api_key=MI_API_KEY

Endpoints v1

Selecciona un endpoint para consultar sus parámetros, peticiones y respuestas.

El balance está expresado en Dólares, la cantidad de SMS que usted puede enviar está sujeta a las tarifas vigentes para el momento de su envío. Le recomendamos siempre consultar su balance antes de envíar una campaña de mensajería para ahorrarse peticiones fallidas.

HTTP Request
/balance

Ejemplo de request:

curl https://www.enviatusms.com/api/v1/balance?api_key=MI_API_KEY

Parámetros retornados

Parámetro Tipo Descripción
status string ok al obtener una respuesta válida o error cuando haya un problema
sms array Cantidad de SMS que puede enviar por cada operadora con su balance actual
balance decimal Cantidad de dólares disponibles

Ejemplo de response JSON:

{
  "status": "ok",
  "sms": {
    "movistar": 100,
    "digitel": 200,
    "movilnet": 50
  },
  "balance": 4.50
}

Los mensajes de texto enviados a través de la API serán programados para su envío de forma inmediata y se descontarán automáticamente de su balance de usuario.

HTTP Request
/sms-multi

Parámetros disponibles

Parámetro Tipo Descripción
numeros array Un array de números en formato local o internacional hacia donde va dirigido el mensaje de texto.
Un formato de número valido puede ser con código de area: 584241234567 o sin dicho código: 4241234567
texto string|array Texto del mensaje. Máximo 160 caracteres. Caracteres con acentos serán convertidos a su equivalente sin acento. Excepto para la letra é o É.

Puede ser un array de múltiples mensajes de texto, el cual debe ser de la misma cantidad que los números definidos. Esto es útil para enviar un mensaje único para cada número.
permitir_duplicados boolean Permite el envío de múltiples distintos mensajes al mismo número.

Ejemplo de request, enviando el mismo mensaje a todos los números:

curl -X POST -H "Content-Type: application/json" -d '{"numeros":["04265461179", "04244623824"], "texto":"Mensaje de prueba"}' https://www.enviatusms.com/api/v1/sms-multi?api_key=MI_API_KEY

Ejemplo de request, enviando un mensaje personalizado a cada número:

curl -X POST -H "Content-Type: application/json" -d '{"numeros":["04265461179", "04244623824"], "texto":["Mensaje de prueba 0426", "Mensaje de prueba 0424"]}' https://www.enviatusms.com/api/v1/sms-multi?api_key=MI_API_KEY

Parámetros retornados

Parámetro Tipo Descripción
status string ok al obtener una respuesta válida o error cuando haya un problema
campaign_id integer El ID de la campaña creada.
msg string Información adicional de la respuesta obtenida
ignored array Un array de números de celular que no cumplan con el formato de número de celular correcto. Los números ignorados no serán descontados de su balance.
sms_contenido string En caso de error relacionado a un SMS, esta variable contendrá el contenido del mensaje problemático.
precio_usd float El precio en USD de la campaña enviada, descontado de su balance.
cantidad_mensajes integer La cantidad de mensajes a ser enviados (un SMS puede dividirse en varias partes, si la longitud de este supera los 160 caracteres).

Ejemplo de response JSON:

{
  "status": "ok",
  "campaign_id": 1234,
  "msg": "Mensaje enviado con exito. Numeros invalidos ignorados.",
  "ignored": [
    "581234567896",
    "58123456789"
  ],
  "precio_usd": 20.655,
  "cantidad_mensajes": 200
}

Puede realizar una cotización en tiempo real de sus campañas antes del envío, para verificar el monto que será descontado de su balance. Esto es especialmente útil si sus campañas contienen una combinación de números de distintas operadoras, las cuales pueden poseer distintos precios, haciendo el cálculo final más complejo. Esta ruta le facilita conocer la inversión a realizar, números válidos, números inválidos y SMS totales a enviar antes de proceder con el envío real de sus campañas.

HTTP Request
/sms-costo

Parámetros disponibles

Parámetro Tipo Descripción
numeros array Un array de números en formato local o internacional hacia donde va dirigido el mensaje de texto.
Un formato de número valido puede ser con código de area: 584241234567 o sin dicho código: 4241234567
texto string|array Texto del mensaje. Máximo 160 caracteres. Caracteres con acentos serán convertidos a su equivalente sin acento. Excepto para la letra é o É.

Puede ser un array de múltiples mensajes de texto, el cual debe ser de la misma cantidad que los números definidos. Esto es útil para enviar un mensaje único para cada número.
permitir_duplicados boolean Permite el envío de múltiples distintos mensajes al mismo número.

Ejemplo de request, cotizando el mismo mensaje a todos los números:

curl -X POST -H "Content-Type: application/json" -d '{"numeros":["04265461179", "04244623824"], "texto":"Mensaje de prueba"}' https://www.enviatusms.com/api/v1/sms-costo?api_key=MI_API_KEY

Ejemplo de request, cotizando un mensaje personalizado a cada número:

curl -X POST -H "Content-Type: application/json" -d '{"numeros":["04265461179", "04244623824"], "texto":["Mensaje de prueba 0426", "Mensaje de prueba 0424"]}' https://www.enviatusms.com/api/v1/sms-costo?api_key=MI_API_KEY

Parámetros retornados

Parámetro Tipo Descripción
status string ok Si la campaña es válida para ser enviada o error si existe algún error.
msg string El mensaje de error en caso del status ser error
precio_usd float El monto total en USD de la campaña
numeros_validos integer La cantidad de números válidos
numeros_invalidos integer La cantidad de números inválidos (no son sumados al precio)
cantidad_mensajes integer La cantidad de mensajes de texto que serán enviados. Si la longitud del mensaje de texto es de 160 caracteres o menos, esta cantidad coincidirá con el total de números válidos, de lo contrario se hará el cálculo según la cantidad de partes que posea cada mensaje.

Ejemplo de response JSON:

{
  "status": "ok",
  "precio_usd": 20.655,
  "numeros_validos": 200,
  "numeros_invalidos": 0,
  "cantidad_mensajes": 200
}

Puede consultar toda la información de una campaña, ya sea creada desde la API o desde nuestra interfaz.

HTTP Request
/campaign/{id}

Parámetros disponibles

Parámetro Tipo Descripción
id integer Parámetro de ruta, el ID de la campaña a consultar.

Ejemplo de request:

curl https://www.enviatusms.com/api/v1/campaign/1?api_key=MI_API_KEY

Parámetros retornados

Parámetro Tipo Descripción
status string ok al obtener una respuesta válida o error cuando haya un problema
message_text string El contenido del mensaje de texto
created_at string Fecha de creación de la campaña. En formato: YYYY-MM-DD H:m:s
send_at string Fecha de envío programado de la campaña. En formato: YYYY-MM-DD H:m:s
approved integer 1 o 0 Si la campaña fue aprobada o no (en caso de pasar por moderación)
cancelled integer 1 o 0 Si la campaña fue cancelada por el administrador.
from_api integer 1 o 0 Si la campaña fue creada desde la API o no.
stats object Estadísticas generales de la campaña. Ver descripción de los valores retornados abajo.
stats.total_numbers integer La cantidad total de números de teléfono en esta campaña.
stats.total_sms integer La cantidad total de mensajes de texto a enviar.
stats.pending integer La cantidad de mensajes de texto pendientes por enviar. 0 significa que todos los mensajes fueron enviados, por lo que la campaña se puede considerar "completa".
stats.delivered integer La cantidad de mensajes de texto entregados.
stats.failed integer La cantidad de mensajes de texto fallidos.
numbers_stats object Estadísticas individuales de cada número. Ver descripción de los valores retornados abajo.
numbers_stats.mobile_number integer El número de teléfono en formato internacional.
numbers_stats.status integer
  • 0 SMS pendiente por enviar.
  • 1 SMS entregado por la operadora.
  • 4 SMS eliminado, no será enviado.
  • 7 SMS rechazado por la operadora.
numbers_stats.processed integer 0 o 1 Si el mensaje ya fue procesado por nuestra plataforma.
shortlink_stats object|null Estadísticas individuales del link corto, en caso de haber usado uno. Ver descripción de los valores retornados abajo.
shortlink_stats.short_url string La URL acortada utilizada nuestro servicio etsms.me
shortlink_stats.orig_url string La URL original que fue acortada.
shortlink_stats.total_clicks integer La cantidad de clics totales en el link.
shortlink_stats.unique_clicks integer La cantidad de clics únicos (por IP) en el link.
shortlink_stats.total_views integer La cantidad de visualizaciones del link. Este valor está sujeto a la conexión a internet del usuario al momento de leer el SMS y si su dispositivo soporta dicha carácteristica.
shortlink_stats.location_unique_clicks object La cantidad de clics únicos (por IP) en el link, agrupados por país, región y ciudad.

Ejemplo de response JSON:

{
  "status": "ok",
  "message_text": "Mi campaña de mensajeria",
  "created_at": "2023-04-28 12:05:17",
  "send_at": "2023-04-28 12:05:17",
  "approved": 1,
  "cancelled": 0,
  "from_api": 0,
  "stats": {
    "total_numbers": 2,
    "total_sms": 2,
    "pending": 2,
    "delivered": 0,
    "failed": 0
  },
  "numbers_stats": [
    {
      "mobile_number": 584244623824,
      "status": 0,
      "processed": 0
    },
    {
      "mobile_number": 584123658866,
      "status": 0,
      "processed": 0
    }
  ],
  "shortlink_stats": {
    "short_url": "https://etsms.me/001",
    "orig_url": "https://www.enviatusms.com",
    "total_clicks": 0,
    "unique_clicks": 0,
    "total_views": 0
  }
}

Puede acortar cualquier enlace para ahorrar caracteres en sus mensajes y obtener métricas de las visualizaciones y clics en el mismo. Nuestro servicio etsms.me le permite acortar hasta 10 enlaces diarios. Si necesitas más enlaces cortos por día, contáctanos.

HTTP Request
/acortar-url

Parámetros disponibles

Parámetro Tipo Descripción
link string Una URL correctamente formada (con su protocolo http o https): https://www.mi-url-a-acortar.com

Ejemplo de request:

curl -X POST -H "Content-Type: application/json" -d '{"link":"https://www.mi-url-a-acortar.com"}' https://www.enviatusms.com/api/v1/acortar-url?api_key=MI_API_KEY

Parámetros retornados

Parámetro Tipo Descripción
success boolean true al obtener una respuesta válida o false cuando haya un problema
error string Información adicional de la respuesta obtenida en caso de error
orig_link string La URL original que fue acortada: https://www.mi-url-a-acortar.com
link string La URL acortada https://etsms.me/XYZ
link_no_protocol string La URL acortada sin su protocolo (http o https) etsms.me/XYZ
id string El identificador único de la URL acortada (los caracteres luego de etsms.me/): XYZ

Ejemplo de response JSON:

{
  "success": true,
  "orig_link": "https://www.mi-url-a-acortar.com",
  "link": "https://etsms.me/XYZ",
  "link_no_protocol": "etsms.me/XYZ",
  "id": "XYZ"
}

Puede reutilizar un enlace acortado ya generado, asignando una nueva URL al mismo.

HTTP Request
/modificar-url-acortado

Parámetros disponibles

Parámetro Tipo Descripción
id string El ID del link que desea modificar. Debe haber sido generado por su usuario previamente. Por ejemplo: XYZ
link string Una URL correctamente formada (con su protocolo http o https): https://www.mi-url-a-acortar.com

Ejemplo de request:

curl -X PUT -H "Content-Type: application/json" -d '{"id":"XYZ","link":"https://www.mi-url-a-acortar.com"}' https://www.enviatusms.com/api/v1/modificar-url-acortado?api_key=MI_API_KEY

Parámetros retornados

Parámetro Tipo Descripción
success boolean true al obtener una respuesta válida o false cuando haya un problema
error string Información adicional de la respuesta obtenida en caso de error
orig_link string La URL original que fue acortada: https://www.mi-url-a-acortar.com
link string La URL acortada https://etsms.me/XYZ
link_no_protocol string La URL acortada sin su protocolo (http o https) etsms.me/XYZ
id string El identificador único de la URL acortada (los caracteres luego de etsms.me/): XYZ

Ejemplo de response JSON:

{
  "success": true,
  "orig_link": "https://www.mi-url-a-acortar.com",
  "link": "https://etsms.me/XYZ",
  "link_no_protocol": "etsms.me/XYZ",
  "id": "XYZ"
}

Ejemplos de Códigos

PHP 8.3 o posterior, con la extensión cURL. Guarda la clave en ENVIATUSMS_API_KEY y utiliza esta función con los ejemplos siguientes. La URL contiene la clave: no la registres.

function requestHelper(string $path, ?array $data = null): array
{
    $key = getenv('ENVIATUSMS_API_KEY');
    if (!$key) {
        throw new RuntimeException('Falta ENVIATUSMS_API_KEY');
    }

    $url = 'https://www.enviatusms.com/api/v1/' . $path
        . '?' . http_build_query(['api_key' => $key]);
    $ch = curl_init($url);

    $options = [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
    ];
    if ($data !== null) {
        $options[CURLOPT_POST] = true;
        $options[CURLOPT_HTTPHEADER] = ['Content-Type: application/json'];
        $options[CURLOPT_POSTFIELDS] = json_encode($data, JSON_THROW_ON_ERROR);
    }

    curl_setopt_array($ch, $options);
    $body = curl_exec($ch);
    if ($body === false) {
        throw new RuntimeException(curl_error($ch));
    }

    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($status >= 400) {
        throw new RuntimeException("HTTP $status: $body");
    }

    $result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
    if (!is_array($result)) {
        throw new RuntimeException('Respuesta inesperada');
    }
    if (
        (isset($result['status']) && $result['status'] !== 'ok') ||
        (isset($result['success']) && $result['success'] !== true)
    ) {
        throw new RuntimeException($result['msg'] ?? $result['error'] ?? 'Error de API');
    }
    if (!isset($result['status']) && !isset($result['success'])) {
        throw new RuntimeException('Respuesta inesperada');
    }

    return $result;
}
                            

Envía el mismo texto a todos los números; la función codifica los datos en JSON y utiliza POST:

$respuesta = requestHelper('sms-multi', [
    'numeros' => ['04241234567', '04261234567'],
    'texto' => 'Hola desde PHP',
]);
echo $respuesta['campaign_id'];
                            

Para personalizar cada SMS, pasa un array de textos del mismo tamaño que numeros:

$respuesta = requestHelper('sms-multi', [
    'numeros' => ['04241234567', '04261234567'],
    'texto' => ['Hola 0424', 'Hola 0426'],
]);
echo $respuesta['campaign_id'];
                        

Cotiza el costo de envío con los mismos datos, sin crear una campaña:

$respuesta = requestHelper('sms-costo', [
    'numeros' => ['04241234567', '04261234567'],
    'texto' => 'Hola desde PHP',
]);
echo $respuesta['precio_usd'];
                            

También puedes cotizar textos personalizados:

$respuesta = requestHelper('sms-costo', [
    'numeros' => ['04241234567', '04261234567'],
    'texto' => ['Hola 0424', 'Hola 0426'],
]);
echo $respuesta['precio_usd'];
                        

Sin datos adicionales, la función consulta el balance mediante GET:

$respuesta = requestHelper('balance');
echo $respuesta['balance'];
print_r($respuesta['sms']);
                            

Indica el ID de una campaña propia en la ruta:

$idCampana = 1;
$respuesta = requestHelper("campaign/$idCampana");
echo $respuesta['message_text'];
                            
$respuesta = requestHelper('acortar-url', [
    'link' => 'https://example.com',
]);
echo $respuesta['link'];
                            

Python 3.10 o posterior. Instala requests con pip install requests, define ENVIATUSMS_API_KEY en el entorno y utiliza esta función con los ejemplos siguientes. No registres las URLs que contienen la clave.

import os
import requests


def request_api(path: str, data: dict | None = None) -> dict:
    key = os.environ["ENVIATUSMS_API_KEY"]
    method = "GET"
    if data is not None:
        method = "POST"

    response = requests.request(
        method,
        f"https://www.enviatusms.com/api/v1/{path}",
        params={"api_key": key},
        json=data,
        timeout=30,
    )
    if response.status_code >= 400:
        raise RuntimeError(f"HTTP {response.status_code}")

    result = response.json()
    if not isinstance(result, dict):
        raise RuntimeError("Respuesta inesperada")
    if ("status" in result and result["status"] != "ok") or (
        "success" in result and result["success"] is not True
    ):
        raise RuntimeError(result.get("msg") or result.get("error") or "Error de API")
    if "status" not in result and "success" not in result:
        raise RuntimeError("Respuesta inesperada")

    return result
result = request_api("balance")
print(result["balance"])
print(result["sms"])
                                    

Es posible enviar un único mensaje de texto a múltiples números de la siguiente forma:

result = request_api("sms-multi", {
    "numeros": ["04241234567", "04261234567"],
    "texto": "Hola desde Python",
})
print(result["campaign_id"])
                                    

También se puede enviar un mensaje de texto diferente para cada número. Tomando en cuenta que la cantidad de números y de mensajes en los arreglos, deben coincidir:

result = request_api("sms-multi", {
    "numeros": ["04241234567", "04261234567"],
    "texto": ["Hola 0424", "Hola 0426"],
})
print(result["campaign_id"])
                                    

Es posible cotizar un único mensaje de texto a múltiples números de la siguiente forma:

result = request_api("sms-costo", {
    "numeros": ["04241234567", "04261234567"],
    "texto": "Hola desde Python",
})
print(result["precio_usd"])
                                    

También se puede cotizar un mensaje de texto diferente para cada número. Tomando en cuenta que la cantidad de números y de mensajes en los arreglos, deben coincidir:

result = request_api("sms-costo", {
    "numeros": ["04241234567", "04261234567"],
    "texto": ["Hola 0424", "Hola 0426"],
})
print(result["precio_usd"])
                                    
campaign_id = 1
result = request_api(f"campaign/{campaign_id}")
print(result["message_text"])
                                    
result = request_api("acortar-url", {
    "link": "https://example.com",
})
print(result["link"])
                                    

Go (biblioteca estándar). Define ENVIATUSMS_API_KEY como variable de entorno; no guardes la clave en el código ni registres la URL.

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "net/url"
    "os"
    "time"
)

func main() {
    key := os.Getenv("ENVIATUSMS_API_KEY")
    if key == "" {
        panic("Falta ENVIATUSMS_API_KEY")
    }

    endpoint, err := url.Parse("https://www.enviatusms.com/api/v1/sms-multi")
    if err != nil {
        panic(err)
    }
    params := endpoint.Query()
    params.Set("api_key", key)
    endpoint.RawQuery = params.Encode()

    data, err := json.Marshal(map[string]interface{}{
        "numeros": []string{"04241234567"},
        "texto":   "Hola desde Go",
    })
    if err != nil {
        panic(err)
    }

    req, err := http.NewRequest("POST", endpoint.String(), bytes.NewReader(data))
    if err != nil {
        panic(err)
    }
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{Timeout: 30 * time.Second}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    if resp.StatusCode >= 400 {
        panic(fmt.Sprintf("HTTP %d", resp.StatusCode))
    }

    var result struct {
        Status string `json:"status"`
        Msg    string `json:"msg"`
    }
    if err := json.Unmarshal(body, &result); err != nil {
        panic(err)
    }
    if result.Status != "ok" {
        panic(result.Msg)
    }

    fmt.Println(string(body))
}

Rust: requiere reqwest con blocking y json, y serde_json. No registres URLs que contengan la clave.

use std::{env, error::Error, time::Duration};

fn main() -> Result<(), Box<dyn Error>> {
    let key = env::var("ENVIATUSMS_API_KEY")?;
    let mut url = reqwest::Url::parse("https://www.enviatusms.com/api/v1/sms-multi")?;
    url.query_pairs_mut().append_pair("api_key", &key);

    let client = reqwest::blocking::Client::builder()
        .timeout(Duration::from_secs(30))
        .build()?;
    let response = client
        .post(url)
        .json(&serde_json::json!({
            "numeros": ["04241234567"],
            "texto": "Hola desde Rust"
        }))
        .send()?
        .error_for_status()?;

    let result: serde_json::Value = response.json()?;
    if result["status"] != "ok" {
        return Err(format!("API: {}", result["msg"]).into());
    }

    println!("{result}");
    Ok(())
}

Java 11 o posterior; requiere Jackson Databind. Lee la clave del entorno y evita registrar la URL.

import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.time.Duration;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

class Example {
    public static void main(String[] args) throws Exception {
        String key = System.getenv("ENVIATUSMS_API_KEY");
        if (key == null || key.isEmpty()) {
            throw new IllegalStateException("Falta ENVIATUSMS_API_KEY");
        }

        String url = "https://www.enviatusms.com/api/v1/sms-multi?api_key="
            + URLEncoder.encode(key, StandardCharsets.UTF_8);
        String payload = "{\"numeros\":[\"04241234567\"],\"texto\":\"Hola desde Java\"}";

        HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(30))
            .build();
        HttpRequest request = HttpRequest.newBuilder(URI.create(url))
            .timeout(Duration.ofSeconds(30))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() >= 400) {
            throw new IllegalStateException("HTTP " + response.statusCode());
        }

        JsonNode result = new ObjectMapper().readTree(response.body());
        if (!"ok".equals(result.path("status").asText())) {
            throw new IllegalStateException(result.path("msg").asText());
        }

        System.out.println(response.body());
    }
}

C# (.NET 6 o posterior). La API Key se obtiene del entorno; no registres las URLs completas.

using System.Net.Http.Json;
using System.Text.Json;

var key = Environment.GetEnvironmentVariable("ENVIATUSMS_API_KEY");
if (string.IsNullOrEmpty(key)) {
    throw new InvalidOperationException("Falta ENVIATUSMS_API_KEY");
}

var url = "https://www.enviatusms.com/api/v1/sms-multi?api_key=" + Uri.EscapeDataString(key);

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
using var response = await client.PostAsJsonAsync(
    url,
    new { numeros = new[] { "04241234567" }, texto = "Hola desde C#" }
);
response.EnsureSuccessStatusCode();

using var result = await response.Content.ReadFromJsonAsync<JsonDocument>();
if (result is null) {
    throw new InvalidOperationException("Respuesta vacía");
}

if (result.RootElement.GetProperty("status").GetString() != "ok") {
    throw new InvalidOperationException(result.RootElement.GetProperty("msg").GetString());
}

Console.WriteLine(result.RootElement);

v2 · Autenticación por cabecera

La URL base es https://www.enviatusms.com/api/v2. Envía la clave desde las opciones de tu cuenta en Authorization: Bearer MI_API_KEY en todas las peticiones. La clave en la URL o en el JSON no autentica en v2. Usa HTTPS, guarda la clave fuera del código y no registres cabeceras de autorización. Las restricciones de IP y la rotación de claves siguen funcionando igual que en v1.

curl -H "Authorization: Bearer MI_API_KEY" "https://www.enviatusms.com/api/v2/balance"

GET recibe sus parámetros en la ruta; POST y PUT reciben JSON con Content-Type: application/json. Los errores de clave suelen contener status: error y los endpoints de enlaces usan success: false. Comprueba siempre el cuerpo de la respuesta además del código HTTP.

Endpoints v2

En todas las solicitudes envía Authorization: Bearer MI_API_KEY. Los ejemplos incluyen la URL completa, los parámetros y una respuesta representativa. Un error de negocio puede llegar con HTTP 200; revisa status o success. Los envíos reales descuentan balance; cotiza antes de enviar.

El balance está expresado en Dólares, la cantidad de SMS que usted puede enviar está sujeta a las tarifas vigentes para el momento de su envío. Le recomendamos siempre consultar su balance antes de envíar una campaña de mensajería para ahorrarse peticiones fallidas.

Parámetros de petición

ParámetroTipoDescripción
AuthorizationstringCabecera obligatoria con Bearer MI_API_KEY. No recibe otros parámetros.

Petición

curl -H "Authorization: Bearer MI_API_KEY" "https://www.enviatusms.com/api/v2/balance"

Respuesta JSON

ParámetroTipoDescripción
statusstringok al obtener una respuesta válida o error cuando haya un problema
smsarrayCantidad de SMS que puede enviar por cada operadora con su balance actual
balancedecimalCantidad de dólares disponibles
msgstringMensaje cuando status es error.
{
  "status": "ok",
  "sms": {
    "movistar": 100,
    "digitel": 200,
    "movilnet": 50
  },
  "balance": 4.50
}

Programa una campaña de envío inmediato y descuenta el costo de tu balance. Requiere cuenta activa e identidad verificada.

Parámetros de petición (JSON)

ParámetroTipoDescripción
AuthorizationstringCabecera obligatoria con Bearer MI_API_KEY.
numerosarrayUn array de números en formato local o internacional hacia donde va dirigido el mensaje de texto.
Un formato de número valido puede ser con código de area: 584241234567 o sin dicho código: 4241234567
textostring|arrayTexto del mensaje. Máximo 160 caracteres. Caracteres con acentos serán convertidos a su equivalente sin acento. Excepto para la letra é o É.

Puede ser un array de múltiples mensajes de texto, el cual debe ser de la misma cantidad que los números definidos. Esto es útil para enviar un mensaje único para cada número.
permitir_duplicadosbooleanPermite el envío de múltiples distintos mensajes al mismo número.

Petición: mismo mensaje a varios números

curl -X POST "https://www.enviatusms.com/api/v2/sms-multi" \
  -H "Authorization: Bearer MI_API_KEY" -H "Content-Type: application/json" \
  -d '{"numeros":["04241234567","04261234567"],"texto":"Hola desde mi aplicación"}'

Para personalizar el mensaje, sustituye texto por ["Mensaje para 0424","Mensaje para 0426"]; los arrays deben corresponderse con los números válidos.

Respuesta JSON

ParámetroTipoDescripción
statusstringok al obtener una respuesta válida o error cuando haya un problema
campaign_idintegerEl ID de la campaña creada.
msgstringInformación adicional de la respuesta obtenida
ignoredarrayUn array de números de celular que no cumplan con el formato de número de celular correcto. Los números ignorados no serán descontados de su balance.
sms_contenidostringEn caso de error relacionado a un SMS, esta variable contendrá el contenido del mensaje problemático.
precio_usdfloatEl precio en USD de la campaña enviada, descontado de su balance.
cantidad_mensajesintegerLa cantidad de mensajes a ser enviados (un SMS puede dividirse en varias partes, si la longitud de este supera los 160 caracteres).
{
  "status": "ok",
  "campaign_id": 1234,
  "msg": "Mensaje enviado con exito.",
  "precio_usd": 0.04,
  "cantidad_mensajes": 2
}

Cotiza una campaña antes de enviarla; no crea una campaña ni descuenta balance.

Parámetros de petición (JSON)

ParámetroTipoDescripción
AuthorizationstringCabecera obligatoria con Bearer MI_API_KEY.
numerosarrayUn array de números en formato local o internacional hacia donde va dirigido el mensaje de texto.
Un formato de número valido puede ser con código de area: 584241234567 o sin dicho código: 4241234567
textostring|arrayTexto del mensaje. Máximo 160 caracteres. Caracteres con acentos serán convertidos a su equivalente sin acento. Excepto para la letra é o É.

Puede ser un array de múltiples mensajes de texto, el cual debe ser de la misma cantidad que los números definidos. Esto es útil para enviar un mensaje único para cada número.
permitir_duplicadosbooleanPermite el envío de múltiples distintos mensajes al mismo número.

Petición

curl -X POST "https://www.enviatusms.com/api/v2/sms-costo" \
  -H "Authorization: Bearer MI_API_KEY" -H "Content-Type: application/json" \
  -d '{"numeros":["04241234567","04261234567"],"texto":"Hola desde mi aplicación"}'

Respuesta JSON

ParámetroTipoDescripción
statusstringok Si la campaña es válida para ser enviada o error si existe algún error.
precio_usdfloatEl monto total en USD de la campaña
numeros_validosintegerLa cantidad de números válidos
numeros_invalidosintegerLa cantidad de números inválidos (no son sumados al precio)
cantidad_mensajesintegerLa cantidad de mensajes de texto que serán enviados. Si la longitud del mensaje de texto es de 160 caracteres o menos, esta cantidad coincidirá con el total de números válidos, de lo contrario se hará el cálculo según la cantidad de partes que posea cada mensaje.
msgstringEl mensaje de error en caso del status ser error
sms_contenidostringContenido del SMS problemático en algunos errores.
ignoredarrayNúmeros inválidos ignorados en algunos errores.
{
  "status": "ok",
  "precio_usd": 0.04,
  "numeros_validos": 2,
  "numeros_invalidos": 0,
  "cantidad_mensajes": 2
}

Consulta una campaña creada desde la API o desde la interfaz. Solo puedes consultar tus propias campañas.

Parámetros de petición (ruta)

ParámetroTipoDescripción
AuthorizationstringCabecera obligatoria con Bearer MI_API_KEY.
submission_idintegerParámetro de ruta, el ID de la campaña a consultar.

Petición

curl -H "Authorization: Bearer MI_API_KEY" "https://www.enviatusms.com/api/v2/campaign/1234"

Respuesta JSON

ParámetroTipoDescripción
statusstringok al obtener una respuesta válida o error cuando haya un problema
msgstringMensaje cuando status es error.
message_textstringEl contenido del mensaje de texto
created_atstringFecha de creación de la campaña. En formato: YYYY-MM-DD H:m:s
send_atstringFecha de envío programado de la campaña. En formato: YYYY-MM-DD H:m:s
approvedinteger1 o 0 Si la campaña fue aprobada o no (en caso de pasar por moderación)
cancelledinteger1 o 0 Si la campaña fue cancelada por el administrador.
from_apiinteger1 o 0 Si la campaña fue creada desde la API o no.
statsobjectEstadísticas generales de la campaña. Ver descripción de los valores retornados abajo.
stats.total_numbersintegerLa cantidad total de números de teléfono en esta campaña.
stats.total_smsintegerLa cantidad total de mensajes de texto a enviar.
stats.pendingintegerLa cantidad de mensajes de texto pendientes por enviar. 0 significa que todos los mensajes fueron enviados, por lo que la campaña se puede considerar "completa".
stats.deliveredintegerLa cantidad de mensajes de texto entregados.
stats.failedintegerLa cantidad de mensajes de texto fallidos.
numbers_statsarrayEstadísticas individuales de cada número. Ver descripción de los valores retornados abajo.
numbers_stats[].mobile_numberintegerEl número de teléfono en formato internacional.
numbers_stats[].statusinteger
  • 0 SMS pendiente por enviar.
  • 1 SMS entregado por la operadora.
  • 4 SMS eliminado, no será enviado.
  • 7 SMS rechazado por la operadora.
numbers_stats[].processedinteger0 o 1 Si el mensaje ya fue procesado por nuestra plataforma.
shortlink_statsobject | nullEstadísticas individuales del link corto, en caso de haber usado uno. Ver descripción de los valores retornados abajo.
shortlink_stats.short_urlstringLa URL acortada utilizada nuestro servicio etsms.me
shortlink_stats.orig_urlstringLa URL original que fue acortada.
shortlink_stats.total_clicksintegerLa cantidad de clics totales en el link.
shortlink_stats.unique_clicksintegerLa cantidad de clics únicos (por IP) en el link.
shortlink_stats.total_viewsintegerLa cantidad de visualizaciones del link. Este valor está sujeto a la conexión a internet del usuario al momento de leer el SMS y si su dispositivo soporta dicha carácteristica.
shortlink_stats.location_unique_clicksobjectLa cantidad de clics únicos (por IP) en el link, agrupados por país, región y ciudad.
{
  "status": "ok",
  "message_text": "Hola",
  "created_at": "2026-01-01 12:00:00",
  "send_at": "2026-01-01 12:00:00",
  "approved": 1,
  "cancelled": 0,
  "from_api": 1,
  "stats": {
    "total_numbers": 1,
    "total_sms": 1,
    "pending": 0,
    "delivered": 1,
    "failed": 0
  },
  "numbers_stats": [
    {
      "mobile_number": "584241234567",
      "status": 1,
      "processed": 1
    }
  ],
  "shortlink_stats": null
}

Puede acortar cualquier enlace para ahorrar caracteres en sus mensajes y obtener métricas de las visualizaciones y clics en el mismo. Nuestro servicio etsms.me le permite acortar hasta 10 enlaces diarios. Si necesitas más enlaces cortos por día, contáctanos.

Parámetros de petición (JSON)

ParámetroTipoDescripción
AuthorizationstringCabecera obligatoria con Bearer MI_API_KEY.
linkstringUna URL correctamente formada (con su protocolo http o https): https://www.mi-url-a-acortar.com

Petición

curl -X POST "https://www.enviatusms.com/api/v2/acortar-url" \
  -H "Authorization: Bearer MI_API_KEY" -H "Content-Type: application/json" \
  -d '{"link":"https://example.com"}'

Respuesta JSON

ParámetroTipoDescripción
successbooleantrue al obtener una respuesta válida o false cuando haya un problema
errorstringInformación adicional de la respuesta obtenida en caso de error
orig_linkstringLa URL original que fue acortada: https://www.mi-url-a-acortar.com
linkstringLa URL acortada https://etsms.me/XYZ
link_no_protocolstringLa URL acortada sin su protocolo (http o https) etsms.me/XYZ
idstringEl identificador único de la URL acortada (los caracteres luego de etsms.me/): XYZ
{
  "success": true,
  "orig_link": "https://example.com",
  "link": "https://etsms.me/XYZ",
  "link_no_protocol": "etsms.me/XYZ",
  "id": "XYZ"
}

Ejemplos para copiar y pegar

Los siguientes ejemplos envían un SMS mediante v2. Define ENVIATUSMS_API_KEY en tu entorno y sustituye los números y el texto. No incluyas la clave en repositorios ni registros.

Python 3.10 o posterior; instala requests con pip install requests.

import os
import requests

key = os.environ["ENVIATUSMS_API_KEY"]
response = requests.post(
    "https://www.enviatusms.com/api/v2/sms-multi",
    headers={"Authorization": f"Bearer {key}"},
    json={
        "numeros": ["04241234567"],
        "texto": "Hola desde Python",
    },
    timeout=30,
)
response.raise_for_status()

result = response.json()
if result.get("status") != "ok":
    raise RuntimeError(result.get("msg") or "Respuesta inesperada")

print(result["campaign_id"])

PHP 8.3 o posterior, con la extensión cURL.

<?php
$key = getenv('ENVIATUSMS_API_KEY');
if (!$key) {
    throw new RuntimeException('Falta ENVIATUSMS_API_KEY');
}

$payload = json_encode([
    'numeros' => ['04241234567'],
    'texto' => 'Hola desde PHP',
], JSON_THROW_ON_ERROR);

$ch = curl_init('https://www.enviatusms.com/api/v2/sms-multi');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $key,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => $payload,
]);

$body = curl_exec($ch);
if ($body === false) {
    throw new RuntimeException(curl_error($ch));
}

$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
    throw new RuntimeException("HTTP $status: $body");
}

$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if (($result['status'] ?? null) !== 'ok') {
    throw new RuntimeException($result['msg'] ?? 'Respuesta inesperada');
}

echo $result['campaign_id'];
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
    "strings"
    "time"
)

func main() {
    key := os.Getenv("ENVIATUSMS_API_KEY")
    if key == "" {
        panic("Falta ENVIATUSMS_API_KEY")
    }

    data, err := json.Marshal(map[string]interface{}{
        "numeros": []string{"04241234567"},
        "texto":   "Hola desde Go",
    })
    if err != nil {
        panic(err)
    }

    req, err := http.NewRequest("POST", "https://www.enviatusms.com/api/v2/sms-multi", bytes.NewReader(data))
    if err != nil {
        panic(err)
    }
    req.Header.Set("Authorization", "Bearer "+key)
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{Timeout: 30 * time.Second}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    if resp.StatusCode >= 400 {
        panic(fmt.Sprintf("HTTP %d: %s", resp.StatusCode, body))
    }

    var result struct {
        Status string `json:"status"`
        Msg    string `json:"msg"`
    }
    if err := json.Unmarshal(body, &result); err != nil {
        panic(err)
    }
    if result.Status != "ok" {
        panic(strings.TrimSpace(result.Msg))
    }

    fmt.Println(string(body))
}

Requiere reqwest con blocking y json, y serde_json.

use std::{env, error::Error, time::Duration};

fn main() -> Result<(), Box<dyn Error>> {
    let key = env::var("ENVIATUSMS_API_KEY")?;

    let client = reqwest::blocking::Client::builder()
        .timeout(Duration::from_secs(30))
        .build()?;
    let response = client
        .post("https://www.enviatusms.com/api/v2/sms-multi")
        .bearer_auth(key)
        .json(&serde_json::json!({
            "numeros": ["04241234567"],
            "texto": "Hola desde Rust"
        }))
        .send()?
        .error_for_status()?;

    let result: serde_json::Value = response.json()?;
    if result["status"] != "ok" {
        return Err(format!("API: {}", result["msg"]).into());
    }

    println!("{result}");
    Ok(())
}

.NET 6 o posterior.

using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

var key = Environment.GetEnvironmentVariable("ENVIATUSMS_API_KEY");
if (string.IsNullOrEmpty(key)) {
    throw new InvalidOperationException("Falta ENVIATUSMS_API_KEY");
}

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", key);
using var response = await client.PostAsJsonAsync(
    "https://www.enviatusms.com/api/v2/sms-multi",
    new { numeros = new[] { "04241234567" }, texto = "Hola desde C#" }
);
response.EnsureSuccessStatusCode();

using var result = await response.Content.ReadFromJsonAsync<JsonDocument>();
if (result is null) {
    throw new InvalidOperationException("Respuesta vacía");
}

if (result.RootElement.GetProperty("status").GetString() != "ok") {
    throw new InvalidOperationException(result.RootElement.GetProperty("msg").GetString());
}

Console.WriteLine(result.RootElement);

Java 11 o posterior; requiere Jackson Databind para interpretar JSON.

import java.net.URI;
import java.net.http.*;
import java.time.Duration;

            import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

class Example {
    public static void main(String[] args) throws Exception {
        String key = System.getenv("ENVIATUSMS_API_KEY");
        if (key == null || key.isEmpty()) {
            throw new IllegalStateException("Falta ENVIATUSMS_API_KEY");
        }

        String payload = "{\"numeros\":[\"04241234567\"],\"texto\":\"Hola desde Java\"}";

        HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(30))
            .build();
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://www.enviatusms.com/api/v2/sms-multi"))
            .timeout(Duration.ofSeconds(30))
            .header("Authorization", "Bearer " + key)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() >= 400) {
            throw new IllegalStateException("HTTP " + response.statusCode());
        }

        JsonNode result = new ObjectMapper().readTree(response.body());
        if (!"ok".equals(result.path("status").asText())) {
            throw new IllegalStateException(result.path("msg").asText());
        }

        System.out.println(response.body());
    }
}