Developer guide

Como automatizar publicaciones en redes sociales con Python

Ya sea que estes construyendo un pipeline de contenido para tu startup, automatizando publicaciones para clientes o integrando la publicacion social en tu producto SaaS, Python lo hace facil. Este tutorial te lleva desde tu primera subida hasta un script de automatizacion listo para produccion.

Por qué Python para automatización de redes sociales

Python es el lenguaje por excelencia para automatizacion. Es legible, tiene un ecosistema enorme y es perfecto para scripts que se ejecutan en un horario. Y cuando se trata de publicar en redes sociales programaticamente, la alternativa a usar una API como Upload-Post es construir integraciones OAuth para cada plataforma tu mismo. Eso significa manejar la Content Posting API de TikTok, la Graph API de Instagram, la Data API de YouTube, y asi sucesivamente. Cada una con su propio flujo de autenticacion, limites de uso y peculiaridades.

Con la API de publicación en redes sociales, haces una sola llamada API y publica en las diez plataformas. El SDK de Python lo simplifica aun mas.

Configurar tu entorno

1. Instalar el SDK

pip install upload-post

2. Obtener tu API key

Crea una cuenta gratuita en app.upload-post.com y genera una API key desde el panel de API Keys. Guardala como variable de entorno:

export UPLOAD_POST_API_KEY="your-api-key-here"

3. Conectar tus cuentas sociales

En el panel de Upload-Post, crea un perfil (por ejemplo "mybrand") y conecta tus cuentas de TikTok, Instagram, YouTube y cualquier otra plataforma donde quieras publicar. El nombre del perfil es lo que referenciaras en tu codigo.

Tu primera subida: publica un video

import os
from upload_post import UploadPostClient

client = UploadPostClient(
    api_key=os.environ["UPLOAD_POST_API_KEY"]
)

response = client.upload_video(
    video_path="my-video.mp4",
    title="Nuestro nuevo producto en acción",
    user="mybrand",
    platforms=["tiktok", "instagram", "youtube"]
)

if response["success"]:
    for platform, result in response["results"].items():
        if result["success"]:
            print(f"{platform}: {result['url']}")
        else:
            print(f"{platform}: upload failed")
else:
    print("Upload failed:", response)

Eso es un script funcional. Ejecutalo y tu video se publica en tres plataformas. Ahora vamos a hacerlo mas potente.

Publicar fotos y carruseles

response = client.upload_photos(
    photos=["slide-1.jpg", "slide-2.jpg", "slide-3.jpg"],
    title="Lookbook de la colección de verano",
    description="Cada pieza, hecha en Portugal. Compra en el enlace en la biografía.",
    user="mybrand",
    platforms=["instagram", "tiktok", "linkedin"]
)

print(response)

Instagram crea un carrusel, TikTok crea un slideshow y LinkedIn muestra una publicacion multi-imagen. Cada plataforma recibe el formato que prefiere.

Publicar contenido de texto

Para publicaciones solo de texto (piensa en hilos de Twitter, actualizaciones de LinkedIn o publicaciones de Reddit):

response = client.upload_text(
    title="Acabamos de lanzar una gran actualización a nuestra API. Aquí está lo que cambió...",
    user="mybrand",
    platforms=["x", "linkedin", "threads", "bluesky"]
)

print(response)

Si tu texto excede el limite de caracteres en una plataforma, la API lo gestiona de forma inteligente. En X, el texto de mas de 280 caracteres se convierte automaticamente en un hilo. En Threads, la division ocurre a los 500 caracteres. En Bluesky, a los 300.

Usar parametros especificos por plataforma

El parametro title establece el caption por defecto para todas las plataformas, pero a menudo querras texto diferente para cada una. Asi se personaliza por plataforma:

import requests
import os

API_KEY = os.environ["UPLOAD_POST_API_KEY"]

with open("product-demo.mp4", "rb") as video:
    response = requests.post(
        "https://api.upload-post.com/api/upload",
        headers={"Autorización": f"Apikey {API_KEY}"},
        files={"video": video},
        data={
            "user": "mybrand",
            "title": "Check this out",
            # Platform specific titles
            "tiktok_title": "POV: tu producto se vende solo #ecommerce #dropshipping",
            "instagram_title": "Nuevo lanzamiento. Enlace en la biografía para acceso anticipado.",
            "youtube_title": "Demostración del producto | Revisión completa",
            "youtube_description": "En este video te mostramos exactamente cómo funciona...",
            "linkedin_title": "Emocionados de compartir nuestro último lanzamiento de producto con la comunidad.",
            # Platform specific settings
            "platform[]": ["tiktok", "instagram", "youtube", "linkedin"],
            "privacy_level": "PUBLIC_TO_EVERYONE",
            "media_type": "REELS",
            "tags[]": ["product", "demo", "review"],
            "privacyStatus": "public",
        }
    )

print(response.json())

Este ejemplo usa la libreria requests directamente en lugar del SDK, lo que te da acceso a cada parametro de la API. Consulta la referencia completa de la API para todas las opciones disponibles por plataforma.

Schedule posts for later

from datetime import datetime, timedelta

# Schedule for tomorrow at 9 AM
tomorrow_9am = (datetime.now() + timedelta(days=1)).replace(
    hour=9, minute=0, second=0, microsecond=0
)

response = client.upload_video(
    video_path="tomorrows-content.mp4",
    title="¡Buenos días! Contenido fresco para tu feed",
    user="mybrand",
    platforms=["tiktok", "instagram"],
    scheduled_date=tomorrow_9am.isoformat(),
    timezone="America/New_York"
)

print(f"¡Programado! ID de trabajo: {response['job_id']}")
print(f"Se publicará en: {response['scheduled_date']}")

Puedes programar hasta 365 dias de anticipacion. Para mas detalles sobre programacion y el sistema de cola, lee nuestra guia de programacion.

Construir una automatización completa: vigilante de carpeta

Aqui tienes un script practico que vigila una carpeta en busca de nuevos archivos de video y los sube automaticamente. Esto es genial para agencias que reciben contenido de clientes en una carpeta compartida:

import os
import time
import json
from upload_post import UploadPostClient

client = UploadPostClient(
    api_key=os.environ["UPLOAD_POST_API_KEY"]
)

WATCH_FOLDER = "/path/to/content/inbox"
PROCESSED_FILE = "/path/to/content/processed.json"
CHECK_INTERVAL = 60  # seconds

def load_processed():
    if os.path.exists(PROCESSED_FILE):
        with open(PROCESSED_FILE) as f:
            return set(json.load(f))
    return set()

def save_processed(processed):
    with open(PROCESSED_FILE, "w") as f:
        json.dump(list(processed), f)

def upload_video(filepath):
    filename = os.path.basename(filepath)
    title = filename.rsplit(".", 1)[0].replace("-", " ").replace("_", " ")

    response = client.upload_video(
        video_path=filepath,
        title=title,
        user="mybrand",
        platforms=["tiktok", "instagram", "youtube"],
        add_to_queue=True,
        async_upload=True
    )
    return response

print(f"Watching {WATCH_FOLDER} for new videos...")

processed = load_processed()

while True:
    for filename in os.listdir(WATCH_FOLDER):
        if filename in processed:
            continue
        if not filename.lower().endswith((".mp4", ".mov")):
            continue

        filepath = os.path.join(WATCH_FOLDER, filename)
        print(f"New file detected: {filename}")

        try:
            result = upload_video(filepath)
            print(f"  Queued successfully: {result.get('job_id', 'done')}")
            processed.add(filename)
            save_processed(processed)
        except Exception as e:
            print(f"  Error: {e}")

    time.sleep(CHECK_INTERVAL)

Ejecuta este script en segundo plano (o como servicio de systemd) y cada vez que alguien deje un video en la carpeta, se publicara en todas tus plataformas conectadas. Si necesitas algo mas robusto, considera usar n8n o Make.com para un workflow gestionado.

Trabaja con la API directamente (sin el SDK)

Si prefieres no usar el SDK o necesitas control de mas bajo nivel, puedes usar la libreria requests directamente. Aqui tienes el equivalente de la subida con SDK:

import requests

API_KEY = "your-api-key-here"
API_URL = "https://api.upload-post.com/api/upload"

# Upload a video
with open("video.mp4", "rb") as f:
    response = requests.post(
        API_URL,
        headers={"Autorización": f"Apikey {API_KEY}"},
        files={"video": ("video.mp4", f, "video/mp4")},
        data={
            "user": "mybrand",
            "title": "Publicado con solicitudes de Python",
            "platform[]": ["tiktok", "instagram"],
        }
    )

print(response.status_code)
print(response.json())

Validar tu clave API

Antes de ejecutar un lote grande, es buena idea validar que tu clave funciona y comprobar los limites de tu plan:

response = requests.get(
    "https://api.upload-post.com/api/uploadposts/me",
    headers={"Autorización": f"Apikey {API_KEY}"}
)

data = response.json()
print(f"Email: {data['email']}")
print(f"Plan: {data['plan']}")

Buenas prácticas de manejo de errores

Cuando construyes scripts para produccion, maneja estos escenarios comunes:

import requests

def upload_with_retry(video_path, title, platforms, max_retries=3):
    for attempt in range(max_retries):
        try:
            with open(video_path, "rb") as f:
                response = requests.post(
                    "https://api.upload-post.com/api/upload",
                    headers={"Autorización": f"Apikey {API_KEY}"},
                    files={"video": f},
                    data={
                        "user": "mybrand",
                        "title": title,
                        "platform[]": platforms,
                        "async_upload": "true",
                    },
                    timeout=120
                )

            if response.status_code == 200:
                return response.json()
            elif response.status_code == 429:
                # Rate limited, check usage
                usage = response.json().get("usage", {})
                print(f"Rate limited. Used {usage.get('count')}/{usage.get('limit')}")
                return None
            elif response.status_code == 401:
                print("Invalid API key")
                return None
            else:
                print(f"Attempt {attempt + 1} failed: {response.status_code}")

        except requests.exceptions.Timeout:
            print(f"Attempt {attempt + 1} timed out, retrying...")

    print(f"Todos los {max_retries} intentos fallaron para {video_path}")
    return None

Consultar historial de subidas

Puedes obtener tu historial de subidas para verificar que se proceso correctamente o construir un panel de reportes:

response = requests.get(
    "https://api.upload-post.com/api/uploadposts/history?page=1&limit=20",
    headers={"Autorización": f"Apikey {API_KEY}"}
)

for entry in response.json()["history"]:
    status = "OK" if entry["success"] else "FAILED"
    print(f"[{status}] {entry['platform']} - {entry['post_title']} - {entry['post_url']}")

Next steps

Ahora que tienes lo basico, aqui van algunas ideas de lo que puedes construir a continuacion:

Empieza a automatizar con Python hoy

Instala el SDK, obtén tu API key y publica tu primer video en menos de 5 minutos. El plan gratuito incluye 10 subidas al mes.

pip install upload-post