> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Publicación masiva

> Programa publicaciones de forma masiva con un archivo CSV

export const XByoNotice = () => <Info>
  <strong>Targeting X/Twitter?</strong> Starting March 31, 2026, all X operations require your own API credentials. After linking X via OAuth, include these 2 headers in your request:
  <br /><br />
  <code>X-Twitter-OAuth1-Api-Key</code> — Your API Key (Consumer Key)<br />
  <code>X-Twitter-OAuth1-Api-Secret</code> — Your API Key Secret (Consumer Secret)
  <br /><br />
  <strong>One-time setup per Ayrshare account.</strong> You create one X Developer App and reuse the same API Key and Secret across every sub-profile / end-user you link. You do <em>not</em> create a new app per customer.
  <br /><br />
  Not linked yet? See the <a href="/dashboard/connect-social-accounts/x-twitter-byo-keys">full setup guide</a> to connect your X account.
  <br /><br />
  Your keys are never logged or stored by Ayrshare.
</Info>;

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "business") {
      displayPlans = ["Launch", "Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Launch", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["premium"]} maxPackRequired={false} />

<XByoNotice />

Programa publicaciones de forma masiva con un archivo CSV (Comma Separated Values) que contenga los datos de las publicaciones.
El Content-Type debe ser `multipart/form-data`.

<Warning>
  Te recomendamos usar el [endpoint Post](/apis/post/post) directamente en lugar de este método masivo para
  programar publicaciones. El endpoint directo ofrece un conjunto de funciones más completo y facilita
  la depuración.
</Warning>

## Parámetros del header

<ParamField header="Authorization" type="string" required>
  Formato: `Authorization: Bearer API_KEY`. Consulta la [descripción general de la API](/apis/overview#authorization) para más
  información.
</ParamField>

<ParamField header="Profile-Key" type="string">
  Profile Key de un User Profile.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  `Content-Type: multipart/form-data`
</ParamField>

## Parámetros del body

<ParamField path="file" type="object">
  Archivo CSV multipart form-data con las publicaciones programadas. Consulta más abajo la [plantilla CSV](#csv-template).
</ParamField>

## Ejemplos de solicitud

Un multipart form-data que contenga un archivo CSV de publicaciones las programará para una fecha futura.

El archivo CSV contiene los siguientes campos (plantilla más abajo) y son obligatorios:

<ul class="custom-bullets">
  <li>`post`: el texto de la publicación.</li>
  <li>`platforms`: lista separada por comas de plataformas, por ejemplo "twitter, facebook, instagram".</li>
  <li>`mediaUrls`: URL del medio, como una imagen o video, para incluir en la publicación.</li>

  <li>
    `scheduleDate`: fecha y hora para programar la publicación en formato UTC. Por ejemplo, usa el formato
    `YYYY-MM-DDThh:mm:ssZ` y envíalo como `2026-07-08T12:30:00Z`. Consulta
    [utctime](https://www.utctime.net/) para ver más ejemplos.
  </li>
</ul>

<Warning>
  No envíes publicaciones duplicadas con menos de dos días de diferencia.

  Si la scheduleDate de dos publicaciones con exactamente el mismo texto están a menos de tres días de diferencia, la segunda publicación será rechazada cuando llegue la scheduleDate.
  Esto se hace para proteger tu cuenta en las redes; pueden suspender o hacer shadow-ban a cuentas con publicaciones duplicadas frecuentes.
</Warning>

## Plantilla CSV

Descarga la plantilla y guárdala como archivo .csv.

[Plantilla CSV de Ayrshare](https://img.ayrshare.com/012/Ayrshare_CSV_Template.csv)

<RequestExample>
  ```bash cURL theme={"system"}
  curl \
  -H "Authorization: Bearer API_KEY" \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@"./Ayrshare CSV Template.csv"' \
  -X POST https://api.ayrshare.com/api/post/bulk
  ```

  ```javascript JavaScript theme={"system"}
  const API_KEY = "API_KEY";
  const FormData = require("form-data");
  const fs = require("fs");

  const formData = new FormData();
  formData.append("file", fs.createReadStream("./Ayrshare CSV Template.csv"));

  fetch("https://api.ayrshare.com/api/post/bulk", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      ...formData.getHeaders()
    },
    body: formData
  })
    .then((res) => res.json())
    .then((data) => {
      console.log(JSON.stringify(data));
    })
    .catch((error) => {
      console.log(error);
    });
  ```

  ```python Python theme={"system"}
  import requests

  API_KEY = "API_KEY"

  # Open the CSV file in binary read mode
  with open('./Ayrshare CSV Template.csv', 'rb') as file:
      # Prepare the files dictionary for the multipart/form-data request
      files = {'file': file}

      # Set up the authorization header
      headers = {'Authorization': f'Bearer {API_KEY}'}

      try:
          # Make the POST request to the API
          response = requests.post(
              'https://api.ayrshare.com/api/post/bulk',
              headers=headers,
              files=files
          )

          # Parse and print the JSON response
          data = response.json()
          print(data)

      except Exception as e:
          print(f"Error: {e}")
  ```
</RequestExample>

<ResponseExample>
  ```javascript 200: OK Example with two scheduled posts. theme={"system"}
  {
      "status": "success",
      "posts": [
          {
              "status": "scheduled",
              "scheduleDate": "4/6/21 12:50",
              "id": "X3uTExuEJhyM3u8wCRsA",
              "post": "A great post"
          },
          {
              "status": "scheduled",
              "scheduleDate": "4/6/21 13:00",
              "id": "8RGrekuxMnVa7lVnARFm",
              "post": "An even better post"
          }
      ]
  }
  ```
</ResponseExample>
