arplyx (Python SDK)
SDK oficial de Arplyx para Python: enviá mensajes y broadcasts de WhatsApp y consultá estados con una API tipada.
Instalación
pip install arplyx
Requiere Python 3.8+.
Uso
from arplyx import Arplyx, ArplyxError
client = Arplyx(api_key="ak_live_...")
# Iniciar la conversación con una plantilla aprobada (canal whatsapp_meta, el default)
msg = client.send_message(
external_id="pedido-10045",
to="+5491155551234",
template={"name": "pedido_confirmado", "language": "es_AR", "body": ["Juan", "10045"]},
)
print(msg.message_id, msg.status)
# Texto libre: solo dentro de la ventana de 24 h que abre el contacto al escribirte
client.send_message(
external_id="respuesta-10045",
to="+5491155551234",
text="Tu pedido fue confirmado.",
)
# Consultar estado (por message_id o por tu external_id)
status = client.get_message("pedido-10045")
print(status.status) # pending | queued | sent | delivered | read | failed
Plantillas (Meta Official)
client.send_message(
external_id="pedido-10045",
to="+5491155551234",
channel="whatsapp_meta",
template={"name": "pedido_confirmado", "language": "es_AR", "body": ["Juan", "10045"]},
)
Si la plantilla usa parámetros nombrados, body es una lista de {"name": ..., "text": ...} (solo BODY; el header sigue posicional y los botones no se soportan: un buttons no vacío responde 400).
Catálogo de plantillas
Requiere una API key con templateAccess (read para listar, manage para crear) y que la cuenta tenga credencial de gestión cargada por el operador.
page = client.list_templates(account_id, status="APPROVED")
for t in page.templates:
print(t.name, t.language, t.status, t.parameter_format)
created = client.create_template(
account_id,
name="turno_recordatorio",
language="es_AR",
category="UTILITY",
body="Hola {{nombre}}, te recordamos tu turno el {{fecha}}.",
examples=[{"name": "nombre", "text": "Juan"}, {"name": "fecha", "text": "13/10"}],
)
print(created.template.status) # PENDING: la aprueba Meta
Diagnóstico de un envío
get_message devuelve, además de los estados, provider_message_id (wamid), processing (reintentos internos) y error con el code de Arplyx y el detalle saneado del proveedor (provider.code, subcode, fbtrace_id). Un 201 al enviar no prueba entrega: mirá status.
Imágenes y documentos
El archivo se referencia por URL pública HTTPS (Arplyx no lo almacena). Imágenes JPEG/PNG hasta 5 MB; documentos PDF/Office/texto hasta 20 MB. caption y filename son opcionales. Como el texto libre, por Meta Official un adjunto solo se entrega dentro de la ventana de 24 h.
client.send_message(
external_id="pedido-10045-foto",
to="+5491155551234",
image={"url": "https://cdn.tuempresa.com/pedidos/10045/foto.jpg", "caption": "Tu pedido salió a reparto."},
)
client.send_message(
external_id="factura-A-0001-00012345",
to="+5491155551234",
document={
"url": "https://cdn.tuempresa.com/facturas/A-0001-00012345.pdf",
"filename": "Factura A-0001-00012345.pdf",
"caption": "Te adjunto la factura de este mes.",
},
)
Si la URL no se puede descargar, el mensaje termina en failed con last_error_code: MEDIA_UNAVAILABLE (sin reintentos).
Adjuntar el archivo directamente (sin URL)
Pasá path (ruta local) o file (bytes o file-like) y el SDK lo sube a Arplyx (POST /media) antes de enviar. Arplyx guarda el archivo solo hasta que el mensaje termina de procesarse.
client.send_message(
external_id="factura-A-0001-00012345",
to="+5491155551234",
document={"path": "./factura.pdf", "filename": "Factura A-0001-00012345.pdf"},
)
# O en dos pasos, para reusar el media_id en varios envíos:
media = client.upload_media("./promo.jpg")
client.send_message(external_id="promo-1", to="+549...", image={"media_id": media.media_id})
Broadcast a una lista (planes Basic/Pro)
Los broadcasts son texto libre: por Meta Official solo llegan a los contactos con la ventana de 24 h abierta (al resto les queda failed con OUTSIDE_WINDOW). Para iniciar conversaciones enviá una plantilla con send_message.
client.send_broadcast(
external_id="promo-junio-2026",
list_id="TU_LIST_ID",
text="Gracias por escribirnos: ya podés reservar tu turno desde la web.",
channel="whatsapp_meta",
)
Listar cuentas de WhatsApp
for acc in client.list_whatsapp_accounts():
print(acc.id, acc.type, acc.status) # acc.id se usa como whatsapp_account_id
¿Este número ya me escribió? (opt-in)
Para confirmar el opt-in, pedile a la persona que te escriba primero y verificalo antes de habilitarla como destino:
sender = client.get_inbound_sender("+5493411234567")
if sender.has_written:
print(sender.first_inbound_at, sender.inbound_count)
# Batch (máx 200 números por request)
senders = client.lookup_inbound_senders(["+5493411234567", "+5491155551234"])
El dato sobrevive a la retención de mensajes y está disponible en todos los
planes. "Nunca escribió" devuelve has_written=False (no lanza).
Listar mensajes entrantes (plan Pro)
page = client.list_inbound_messages(from_phone="+5493411234567")
for m in page.inbound_messages:
print(m.received_at, m.text)
Manejo de errores
try:
client.send_message(external_id="x", to="+549...", text="hola")
except ArplyxError as e:
print(e.status) # 400, 401, 409, 422, 429, 500...
print(e.code) # 'validation_error', 'conflict', 'quota_exceeded'...
print(e.details) # detalles por campo si es validation_error
Idempotencia
Todos los envíos usan tu external_id como clave de idempotencia: reintentar con el mismo external_id y payload no duplica el envío. Es seguro reintentar ante timeouts.
Configuración
| Parámetro | Requerido | Default |
|---|---|---|
api_key |
Sí | — |
base_url |
No | https://api.arplyx.com |
timeout |
No | 10.0 |
session |
No | requests.Session() nueva |
Docs de la API: https://docs.arplyx.com/api/ · OpenAPI: https://api.arplyx.com/openapi.yaml
Metadata
Release files for arplyx 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| arplyx-0.5.0.tar.gz | 16.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| arplyx-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.0 kB
Release files / arplyx-0.5.0.tar.gz
| Download URL | arplyx-0.5.0.tar.gz |
|---|---|
| Size | 16.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
256732686552a5365074e3f2359b1b532ccf00d4c6d682187e3e0db2ad7f533b
|
|
BLAKE2b-256 checksum How to use checksums |
fd42d661d70c211d2f6d04c4aa0f9f61045fed057982c2142d64270c7d8326da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / arplyx-0.5.0-py3-none-any.whl
| Download URL | arplyx-0.5.0-py3-none-any.whl |
|---|---|
| Size | 15.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0ba73f9f7bc93aafdc053bf7273c16dca922b9786ccb169188ca342fe8f6a473
|
|
BLAKE2b-256 checksum How to use checksums |
1fad151d293b1a96e35405adc9fc9a2914964c3986297168f661203b67d3520b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Security for arplyx 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.