---
title: "Cómo automatizar publicaciones de Instagram"
date: 2026-09-14
author: "InvisibleAPI Team"
canonical_id: automate-instagram-posts
locale_slug: automatizar-publicaciones-instagram
category: engineering
tags:
  - publishing-api
summary: "Automatizar Instagram es una cola, un despachador y una política de fallos. Aquí está la construcción, con el control de límites y la clave de idempotencia."
draft: false
template: blog
image: blog/automate-instagram-posts/automate-instagram-posts-hero-01-es.png
faq:
  - question: "¿Se pueden programar publicaciones de Instagram desde la API?"
    answer: "No desde la API de Meta por sí sola. Su documentación de publicación de contenido indica que la API no admite programación de forma nativa, así que el calendario lo tiene que llevar tu aplicación. Publicando con InvisibleAPI defines requestedPublishAt en el job y este se despacha a esa hora, y un job programado se puede cancelar antes del despacho."
  - question: "¿Cuántas publicaciones de Instagram se pueden hacer por API en un día?"
    answer: "La documentación de publicación de contenido de Meta indica 100 publicaciones por API dentro de un periodo móvil de 24 horas, y un carrusel cuenta como una sola. La cifra de 25 publicaciones diarias se sigue repitiendo mucho y no es lo que dice la documentación hoy. Verifica el número tú mismo antes de construir un despachador sobre él."
  - question: "¿Automatizar publicaciones va contra las condiciones de Instagram?"
    answer: "Publicar con la API oficial de publicación de contenido es la vía documentada y admitida. Lo que rompe las condiciones es el otro tipo de automatización: herramientas que inician sesión con la contraseña de Instagram del usuario, o que automatizan me gusta, seguimientos y mensajes directos. Las Condiciones de la Plataforma de Meta dicen que una aplicación no debe solicitar ni recopilar por separado las credenciales de acceso de un usuario."
  - question: "¿Cómo se evita que un publicador automático duplique publicaciones?"
    answer: "Dale a cada fila de la cola un id estable y envíalo como clave de idempotencia en la llamada de creación. En InvisibleAPI ese campo es clientRequestId, y una llamada repetida con el mismo valor no publica dos veces. Sin él, cualquier reintento tras un tiempo de espera agotado es una moneda al aire, porque una petición que falló y una que funcionó y perdió la respuesta se ven iguales desde tu código."
seo:
  title: "Cómo automatizar publicaciones de Instagram"
  description: "Automatiza publicaciones de Instagram desde tu código: una cola, un job por fila, programación, control de límites y los cuatro fallos."
  og_image: blog/automate-instagram-posts/automate-instagram-posts-hero-01-es.png
  structured_data: article
---

El trabajo cabe en una frase: publicar en Instagram según un calendario, desde tu propio código, sin que nadie abra la aplicación.

Casi todo lo que se escribe sobre cómo automatizar publicaciones de Instagram responde a otra pregunta. Responde a "qué calendario debería pagar". Esta es la otra respuesta, la de quien ya decidió construirlo, sobre la Graph API de Meta directamente o sobre [una API de publicación unificada](/es/api-de-publicacion/). La construcción tiene tres partes, y solo una es la que los productos enseñan en la demo. Todos los datos de Meta que aparecen abajo se leyeron de su documentación el 14 de septiembre de 2026, y las páginas están enlazadas al final.

{{product-cta:publish-to-instagram}}

## Qué significa realmente automatizar publicaciones de Instagram

Quita las herramientas y un publicador automático son tres cosas.

| Parte | Qué guarda | Cuánto cuesta |
|---|---|---|
| La cola | Qué publicar, dónde y cuándo | Fácil. Es una tabla. |
| El despachador | El bucle que convierte una fila vencida en una publicación | Fácil de empezar, y la parte que decide si esto sobrevive un mes |
| La política de fallos | Qué pasa cuando la publicación no llega | El trabajo entero |

La automatización de publicaciones de Instagram se vende por la primera parte porque la primera parte es la que luce en una demo. Un calendario con arrastrar y soltar es una cola con una persona dentro. Quita a la persona y la cola no cambia en nada, pero las otras dos partes empiezan a importar, porque ya no hay nadie mirando que note que la publicación del martes nunca salió.

Así que la construcción de abajo dedica cuatro líneas a la cola y el resto a lo que pasa después del despacho.

## La cola es un archivo, no una base de datos

Empieza por lo más pequeño que funcione. Un CSV, versionado en el repositorio o guardado en almacenamiento de objetos, con cinco columnas:

| `row_id` | `account` | `media_url` | `caption` | `publish_at` |
|---|---|---|---|---|
| `2026-09-15-launch` | `@yourbrand` | `https://cdn.example.com/launch.jpg` | Nuevo lanzamiento disponible. | `2026-09-15T09:00:00Z` |
| `2026-09-16-behind` | `@yourbrand` | `https://cdn.example.com/studio.jpg` | Detrás de la sesión. | `2026-09-16T09:00:00Z` |

Dos cosas de esta tabla sostienen todo lo demás.

**El media es una URL, no un archivo.** Aquí no hay paso de subida, porque el media se entrega como una URL públicamente accesible. Un enlace a un bucket privado es la razón más frecuente por la que falla la primera publicación automática, y ningún reintento convierte un objeto privado en público.

**`row_id` no es decoración.** Se convierte en la clave de idempotencia de la llamada de creación, que es lo que evita que un cron caído publique dos veces en la siguiente ejecución. Elige ahora algo estable y legible y la sección de reintentos más abajo no te costará nada.

Si prefieres partir de una receta en lugar de un folio en blanco, [un calendario de publicación de Instagram con aprobación](/es/plantillas/instagram-publishing-calendar/) es la misma forma con un paso de revisión delante.

## Una fila, un job de publicación

La preparación son dos pasos: [conecta una cuenta profesional de Instagram](/es/docs/cuentas-sociales/conectar-instagram/) y crea una API key de organización con los scopes `publishing:read` y `publishing:publish`. [La guía de inicio rápido](/es/docs/primeros-pasos/inicio-rapido/) recorre ambos.

Después, una fila se convierte en un job de publicación:

```bash
curl -X POST "https://api.invisibleapi.ai/api/v1/organizations/$ORGANIZATION/publishing/jobs" \
  -H "Authorization: Bearer $INVISIBLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "targets": ["acct_ig_01"],
    "caption": "New drop, live now.",
    "mediaItems": [{ "mediaType": "image", "sourceUrl": "https://cdn.example.com/launch.jpg" }],
    "requestedPublishAt": "2026-09-15T09:00:00Z",
    "clientRequestId": "2026-09-15-launch"
  }'
```

La respuesta es un job, no una publicación:

```json
{
  "id": "job_01K2M4P7",
  "status": "scheduled",
  "clientRequestId": "2026-09-15-launch",
  "requestedPublishAt": "2026-09-15T09:00:00Z"
}
```

Esta es la parte que la mayoría de los tutoriales de automatización se salta. La publicación es asíncrona. Creas un job, la secuencia de publicación de varios pasos de la plataforma corre por detrás, y consultas hasta que el estado llega a `published`. Un tutorial que enseña una llamada de creación devolviendo la URL de una publicación en vivo describe algo que no ocurre, y un despachador escrito sobre esa suposición reporta éxito para publicaciones que luego fallaron.

<div class="blog-callout-gray">

**Sobre los nombres de campo.** La forma de la petición está confirmada en la referencia de la API: `targets`, `mediaItems` con su `mediaType` y `sourceUrl`, `caption`, `requestedPublishAt` y `clientRequestId`, y la llamada de creación devolviendo 202. Lo que sigue sin confirmar es la respuesta del trabajo: el nombre del array `deliveries` y el campo `failureCategory`. Compruébalos en [la referencia de la API](https://app.invisibleapi.ai/docs/static/openapi.en.html) antes de publicar código que los lea.

</div>

## La API de Instagram no programa, así que lo programas tú

Este es el dato sobre el que están construidos los productos de calendario, dicho por Meta: la API de publicación de contenido de Instagram "does not natively support scheduling", no admite programación de forma nativa. Esa sola frase explica por qué existe un mercado de programadores de Instagram.

La programación es, por tanto, algo que asume una capa de publicación, y será tu cron guardando filas hasta que toquen o un campo `requestedPublishAt` cargando con esa responsabilidad por ti. En la construcción de arriba es lo segundo, lo que significa que el despachador puede empujar la semana entera el lunes y dejar de pensar en ello. Un job que aún no se ha despachado todavía se puede cancelar.

En cualquier caso, conoce los estados que lee tu bucle. Un job pasa por `pending`, `scheduled`, `processing`, `preparing`, `submitted` y `polling`, y después llega a uno de estos: `published`, `partial_failure`, `failed`, `action_required` o `canceled`. Cinco finales, no uno, y la diferencia entre tres de ellos es todo el tema de la política de fallos.

## Consulta los límites antes de despachar

Un despachador que se entera de una cuota chocándose con ella ya perdió las publicaciones que tenía en la mano. Hay dos techos, y no son el mismo techo.

**El de Meta.** La documentación de publicación de contenido indica 100 publicaciones por API dentro de un periodo móvil de 24 horas, y un carrusel cuenta como una sola. La cifra antigua de 25 publicaciones al día sigue circulando mucho en textos de terceros y no es lo que dice la documentación hoy, así que presupuesta contra 100 y verifica el número tú mismo antes de construir sobre él.

**El tuyo.** Publicando con InvisibleAPI, cada cuenta conectada puede publicar 100 posts por periodo de facturación, y un endpoint de límites reporta el uso en vivo para que el despachador lea el margen restante antes de empezar un lote.

El comportamiento útil no es detenerse ante una cola llena. Es publicar lo que cabe y reprogramar el resto después del reinicio, lo que convierte un lote de fallos en un lote que llega un día más tarde. [Un control de límites de publicación](/es/plantillas/social-media-publishing-limits/) es esa lógica como receta, y [cuánto cuesta publicar en Instagram](/es/blog/precios-api-instagram/) cubre la pregunta más amplia de contra qué se cuenta el volumen.

## Qué sale mal, y qué hace el código al respecto

Cada fallo que ve tu despachador se resuelve en una de cuatro decisiones, y cada una tiene un dueño distinto.

`invalid_publish_data` es tu error. El caption era demasiado largo, la relación de aspecto estaba fuera de rango, el carrusel tenía demasiados elementos. La misma carga fallará igual para siempre, así que un reintento es cuota tirada. Corrige la fila y crea un job nuevo.

`retryable_provider_failure` es la plataforma teniendo un mal momento. Media todavía procesándose, un contenedor caducado, un error de servidor. Se reintenta automáticamente, y el trabajo de tu bucle es seguir esperando en lugar de escalar.

`provider_action_required` es el problema de una persona, normalmente una concesión de credenciales caducada. Ningún bucle de reintentos puede volver a iniciar sesión por alguien. Muéstralo y detente.

`platform_software_failure` es nuestro. Se enruta a soporte técnico, y tu despachador no hace nada salvo no reintentarlo.

Por eso el `switch` de abajo se apoya en la categoría y no en un código de error del proveedor. Los códigos se añaden y se reclasifican; una clasificación de cuatro valores no.

```ts
const TERMINAL = ["published", "partial_failure", "failed", "action_required", "canceled"];

const NOTIFY = {
  invalid_publish_data: "developer",
  retryable_provider_failure: null,
  provider_action_required: "account_owner",
  platform_software_failure: "support",
} as const;

export async function dispatch(row: QueueRow) {
  const job = await createJob(row);           // clientRequestId = row.row_id
  const final = await pollUntil(job.id, (j) => TERMINAL.includes(j.status));

  if (final.status === "published") return { row: row.row_id, ok: true };

  return final.deliveries.map((d) => ({
    target: d.target,
    retry: d.failureCategory === "retryable_provider_failure",
    notify: NOTIFY[d.failureCategory],
  }));
}
```

Fíjate en que el valor devuelto es por delivery, no por job. Un job puede apuntar a varias cuentas conectadas a la vez, y el mismo contenido puede funcionar en una y fallar en otra. Un caption de 500 caracteres se publica en Instagram y falla la regla de 280 caracteres de X dentro del mismo job, que es exactamente lo que describe `partial_failure`. (Si X está en tu lista, [cuánto cuesta publicar en X](/es/blog/precios-api-x/) cubre su propia tarifa.) Lee las deliveries y el informe dice qué cuenta publicó y cuál no. Lee solo el estado del job y te queda un punto rojo.

Esa distribución es la versión de agencia de esta construcción, cubierta por [publicar una vez en varias cuentas conectadas](/es/plantillas/publish-to-multiple-social-accounts/), y la mitad de barrer los fallos es [la receta de recuperación de publicaciones fallidas](/es/plantillas/failed-social-media-post-recovery/).

![Flujo desde una fila de la cola hasta la publicación, pasando por el control de límites, con las ramas de fallo y de acción requerida.](https://images.invisibleapi.ai/blog/automate-instagram-posts/automate-instagram-posts-flow-01-es.png)

## Lo que un reintento nunca debe hacer

Este es el escenario que rompe en silencio a los publicadores desatendidos. Tu despachador envía la llamada de creación. La conexión agota el tiempo de espera. No tienes respuesta, y no hay forma de distinguir una petición que falló de una que funcionó y perdió su respuesta por el camino.

Si reintentas puedes duplicar la publicación. Si la saltas puedes perderla en silencio. Un cron que corre cada cinco minutos se encontrará este caso, y se lo encontrará a las 3 de la madrugada.

Una clave de idempotencia elimina la elección. El `clientRequestId` de la llamada de creación es esa clave, y una petición repetida con el mismo valor no publica dos veces. Por eso la regla es estrecha y absoluta: **un reintento reutiliza la clave original. Nunca genera una nueva.** Generar un id nuevo dentro de la rama de reintento es la forma más común de que un script con buena pinta produzca publicaciones duplicadas, porque apaga el mecanismo de seguridad justo cuando hacía falta.

Por eso también `row_id` venía del archivo de la cola y no del despachador. La clave pertenece a la fila, no al intento.

## La automatización por la que se restringen cuentas de Instagram

Busca automatización de Instagram y buena parte de lo que vuelve es otra categoría de producto: herramientas que envían mensajes directos automáticos a nuevos seguidores, dan me gusta por hashtag, siguen y dejan de seguir, y librerías que llegan a Instagram iniciando sesión con usuario y contraseña en vez de por la API documentada. Conviene ser preciso sobre por qué esa vía es un riesgo distinto, porque la distinción está publicada y no es cuestión de opinión.

Las Condiciones de la Plataforma de Meta, sección 6.a.iii, dicen que una aplicación "must not separately request or collect a Meta user's login credentials for any Meta Products", no debe solicitar ni recopilar por separado las credenciales de acceso de un usuario de Meta. Una librería que inicia sesión como el usuario hace exactamente eso por diseño: es el mecanismo, no un caso extremo. La sección 2.a es más amplia, y dice que salvo licencia expresa "you will not use, access, integrate with, modify, translate, create derivative works of, reverse engineer, or otherwise exploit Platform or any aspect thereof". Un endpoint no documentado al que se llega haciendo ingeniería inversa de la aplicación móvil no está licenciado expresamente.

La automatización de interacciones cae bajo las Políticas para Desarrolladores. La sección 2 prohíbe participar en "any program that promotes or facilitates the purchase, sale, or exchange of 'Likes', 'Shares', 'Followers', 'Comments'", y la sección 5 describe "creating bots either manually or automatically, at very high frequencies" como spam.

La aplicación de las normas tampoco es teórica. La propia referencia de errores de Instagram de Meta incluye códigos para una cuenta restringida y para actividad restringida por sospecha de spam en la publicación. Existen porque hay cuentas que llegan a ese estado.

Nada de esto aplica a la construcción de este artículo. La API de publicación de contenido es la vía documentada, la cuenta la autoriza con el propio flujo OAuth de Instagram, ninguna contraseña llega nunca a tu código, y el límite de uso es un número publicado que puedes consultar antes de despachar. Esa es la razón honesta para tomar la vía oficial, y aguanta mejor que cualquier comparativa de funciones.

## Publica el bucle, no otro calendario

Tu cola, tu calendario, tu código, y un job de publicación por fila que te dice exactamente qué pasó con cada una.

Conecta una cuenta profesional de Instagram, crea una API key con scopes y mete la primera fila. Cada cuenta empieza con una prueba gratuita de 7 días, y [cómo funciona el precio por volumen](/es/pricing/) explica contra qué se cuenta el uso.

{{product-cta:start-free-trial}}

## Fuentes

Las tres páginas se consultaron el 14 de septiembre de 2026.

- [Guía de publicación de contenido de Instagram](https://developers.facebook.com/docs/instagram-platform/content-publishing), para el límite de 100 publicaciones por periodo móvil de 24 horas, el carrusel contando como una y la ausencia de programación nativa
- [Condiciones de la Plataforma de Meta](https://developers.facebook.com/terms/), para las secciones 2.a y 6.a.iii
- [Políticas para Desarrolladores de Meta](https://developers.facebook.com/devpolicy/), para las secciones 2 y 5
