Documentación de la API

Dirección API: https://2index.ninja/api/v1/

Para realizar una solicitud a la API, debe pasar el token de acceso de portador en el encabezado de autorización.

 curl https://2index.ninja/api/v1/account -H "Authorization: Bearer API_TOKEN"

El token de acceso se puede obtener en la sección correspondiente de la cuenta de usuario.

La respuesta a cada solicitud contiene el parámetro success , que determina si la solicitud se ha realizado correctamente. El parámetro errors " contiene los mensajes de error.

En algunos casos, si se devuelve un error 403, es necesario especificar el agente de usuario, por ejemplo:

 curl https://2index.ninja/api/v1/account -H "Authorization: Bearer API_TOKEN" -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"

Las solicitudes pueden estar limitadas por el hosting, en este caso recomendamos utilizar un proxy.

Métodos para trabajar con una cuenta

Obtener detalles de la cuenta

Debe realizar una solicitud GET a la dirección account

 GET https://2index.ninja/api/v1/account

La respuesta serán datos en formato JSON:

 {
    "success": true,
    "account": {
        "email": "[email protected]",
        "tariff": "White Ninja",
        "balance": 100.0,
        "available_projects": 1,
        "available_links": 100,
        "available_indexation_check_links": 500,
        "link_sending_speed": 100,
        "tariff_available": true,
        "tariff_expiring_date": "2025-01-16T14:26:11.000000Z",
        "email_verified": false,
        "link_cost": "$0.00056"
    }
}

Métodos para trabajar con proyectos

Obtenga una lista de proyectos

Debe realizar una solicitud GET a la dirección project

 GET https://2index.ninja/api/v1/project

La respuesta serán datos en formato JSON:

 {
    "success": true,
    "projects": [
        {
            "id": 1,
            "name": "Project name",
            "type": "indexing",
            "website": "https://domain.com/",
            "status": "in progress",
            "created_at": "2024-03-01 14:34:56",
            "links_type": "internal",
            "google_account_access_granted": 0,
            "links_total": 500,
            "links_sending_speed": 400,
            "links_sent_google": 100,
            "links_sent_yandex": 40,
            "links_sent_bing": 100,
            "in_queue": 360,
            "sent_links": 100,
            "indexed": 30,
            "not_indexed": 0,
            "download_queue_url": "DOWNLOAD_QUEUE_URL",
            "download_sent_url": "DOWNLOAD_SENT_URL",
            "download_indexed_url": "DOWNLOAD_INDEXED_URL",
            "download_unindexed_url": "DOWNLOAD_UNINDEXED_URL"
        },
        {
            "id": "2",
            "name": "Project 2 name",
            "type": "indexing_check",
            "status": "in progress",
            "created_at": "2024-03-01 14:34:56",
            "links_total": 200,
            "links_checking_speed": 100,
            "in_queue": 100,
            "checked": 100,
            "indexed": 70,
            "not_indexed": 30,
            "download_queue_url": "DOWNLOAD_QUEUE_URL",
            "download_indexed_url": "DOWNLOAD_INDEXED_URL",
            "download_unindexed_url": "DOWNLOAD_UNINDEXED_URL",
            "download_all_url": "DOWNLOAD_ALL_URL",
            "download_checked_url": "DOWNLOAD_CHECKED_URL",
        }
        ...
    ]
}

Obtener datos del proyecto

Debe realizar una solicitud GET a la dirección project/{project_id}

 GET https://2index.ninja/api/v1/project/1

La respuesta serán datos en formato JSON:

  • Para el proyecto de indexación:
 {
    "success": true,
    "project": {
        "id": 1,
        "name": "Project name",
        "type": "indexing",
        "website": "https://domain.com/",
        "status": "in progress",
        "created_at": "2024-03-01 14:34:56",
        "links_type": "internal",
        "google_account_access_granted": 0,
        "links_total": 500,
        "links_sending_speed": 400,
        "links_sent_google": 100,
        "links_sent_yandex": 40,
        "links_sent_bing": 100,
        "in_queue": 360,
        "sent_links": 100,
        "indexed": 30,
        "not_indexed": 0,
        "download_queue_url": "DOWNLOAD_QUEUE_URL",
        "download_sent_url": "DOWNLOAD_SENT_URL",
        "download_indexed_url": "DOWNLOAD_INDEXED_URL",
        "download_unindexed_url": "DOWNLOAD_UNINDEXED_URL"
    }
}
  • Para el proyecto de verificación de indexación:
 {
    "success": true,
    "project": {
        "id": "2",
        "name": "Project 2 name",
        "type": "indexing_check",
        "status": "in progress",
        "created_at": "2024-03-01 14:34:56",
        "links_total": 200,
        "links_checking_speed": 100,
        "in_queue": 100,
        "checked": 100,
        "indexed": 70,
        "not_indexed": 30,
        "download_queue_url": "DOWNLOAD_QUEUE_URL",
        "download_indexed_url": "DOWNLOAD_INDEXED_URL",
        "download_unindexed_url": "DOWNLOAD_UNINDEXED_URL",
        "download_all_url": "DOWNLOAD_ALL_URL",
        "download_checked_url": "DOWNLOAD_CHECKED_URL"
    }
}

Crear un proyecto

Debes realizar una solicitud POST a project

 POST https://2index.ninja/api/v1/project

Parámetros de la solicitud:

Campo Tipo Necesariamente Descripción
nombre cadena Nombre del proyecto
sitio web cadena Sí* Dirección del sitio web en el formato https://site.domain/ .
*Obligatorio si el tipo de proyecto es: indexing
para enlaces externos booleano No Proyecto para enlaces externos. Si no se especifica, será solo para uso doméstico.
velocidad de indexación entero No** Velocidad de indexación del proyecto. Si no se especifica, se aplicará toda la velocidad disponible en la cuenta. Se utiliza para proyectos con indexing . Para proyectos con indexing_check , se utiliza checking_speed
comprobando_velocidad entero No** Velocidad de comprobación de enlaces del proyecto. Si no se especifica, se aplicará toda la velocidad disponible en la cuenta. Se utiliza para proyectos con tipo indexing_check . Para proyectos con tipo indexing , se utiliza indexing_speed
tipo cadena No Tipo de proyecto.
Opciones posibles: indexing - indexar enlaces, indexing_check - comprobar enlaces de indexación.
Si no se especifica, se creará un enlace de indexación del proyecto indexing

** Al crear un proyecto de cualquier tipo, puede utilizar los parámetros indexing_speed o checking_speed , son alias entre sí, pero si se pasan ambos, se utilizará indexing_speed .

La respuesta serán datos en formato JSON:

 {
    "success": true,
    "message": "The project has been successfully created"
}

Ejemplo de creación de un proyecto de indexación de enlaces: POST https://2index.ninja/api/v1/project

 name: Project 1 website: https://website.com for_external_links: 1 indexing_speed: 100

Ejemplo de creación de un proyecto para comprobar la indexación de enlaces: POST https://2index.ninja/api/v1/project

 name: Project 2 checking_speed: 100

Borrar la cola de indexación

Debes realizar una solicitud POST al project/{project_id}/clear_queue

 POST https://2index.ninja/api/v1/project/1/clear_queue

La respuesta serán datos en formato JSON:

 {
    "success": true,
    "message": "The indexing queue has been cleared successfully. X links have been removed"
}

O se devolverá el mensaje de error correspondiente:

 {
    "success": false,
    "errors": ["Project not found"]
}

Métodos para trabajar con enlaces

Añadir enlaces

Necesitas hacer una solicitud POST para link/add

 POST https://2index.ninja/api/v1/link/add

Parámetros de la solicitud:

Campo Necesariamente Descripción
id del proyecto Identificación del proyecto
campo de golf Lista de enlaces. Puede pasarse como un array de enlaces o como texto (cada enlace en una línea independiente).
Google No, siempre que Yandex o Bing Enviar enlaces a Google
Yandex No, siempre que Google o Bing Enviar enlaces a Yandex
Bing No, siempre que Google o Yandex Enviar enlaces a Bing
acceso a Google concedido No Se concedió el acceso a la cuenta de Google

La respuesta serán datos en formato JSON:

 {
    "success": true,
    "message": "Links have been successfully added to the project"
}

Si hay enlaces erróneos en la lista, los enlaces no se agregarán y se recibirá el mensaje de error correspondiente como respuesta:

 {
    "success": false,
    "errors": ["You sent invalid links"],
    "invalid_links": ["http://wrong.link"]
}

Para los proyectos de verificación de indexación , los enlaces se añaden de la misma forma que para la indexación. google_access_granted no es obligatorio; se ignorará. Es necesario especificar los motores de búsqueda, pero actualmente la verificación solo está disponible en Google.

Agregar enlaces por nombre de proyecto

Debes realizar una solicitud POST a link/add_simple . Si no existe un proyecto con el nombre especificado, se creará automáticamente con la velocidad de envío máxima.

 POST https://2index.ninja/api/v1/link/add_simple

Parámetros de la solicitud:

Campo Necesariamente Descripción
nombre_del_proyecto No El nombre del proyecto. Si no se especifica, se creará un proyecto llamado "default" .
campo de golf Lista de enlaces. Se puede pasar como matriz o texto (cada enlace en una nueva línea).
Google No, si se especifica Yandex o Bing. Enviar enlaces a Google.
Yandex No, si se especifica Google o Bing. Enviar enlaces a Yandex.
Bing No, si se especifica Google o Yandex. Enviar enlaces a Bing.
acceso a Google concedido No Se ha concedido acceso a su cuenta de Google.

Para los proyectos de verificación de indexación , los enlaces se añaden de la misma forma que para la indexación. google_access_granted no es obligatorio; se ignorará. Es necesario especificar los motores de búsqueda, pero actualmente la verificación solo está disponible en Google.

Ejemplo de solicitud:

 {
    "project_name": "My Website",
    "links": ["https://example.com/page1", "https://example.com/page2"],
    "google": true,
    "yandex": false,
    "bing": true,
    "google_access_granted": false
}

Respuesta si tiene éxito:

 {
    "success": true,
    "message": "Links have been successfully added to the project",
    "project_name": "My Website",
    "project_id": 12345
}

Posibles errores:

  • Si hay algún enlace erróneo en la lista:
 {
    "success": false,
    "errors": ["You sent invalid links"],
    "invalid_links": ["http://wrong.link"]
}
  • Si ocurrió un error al crear un proyecto:
 {
    "success": false,
    "errors": ["Failed to create the project"]
}

Verificar estado del enlace

Realice una solicitud POST a /api/v1/link/status

POST https://2index.ninja/api/v1/link/status

Parámetros de la solicitud:

Campo Obligatorio Descripción
project_id ID del proyecto
link Enlace a verificar
  • Si la solicitud tiene éxito, se devolverá un objeto JSON:
{
    "success": true,
    "link": {
        "id": 34368960,
        "url": "https://2index.ninja/",
        "google": "Sent",
        "yandex": "Sent",
        "bing": "Sent",
        "is_external": 1,
        "google_sent": "2025-08-24 20:10:02",
        "yandex_sent": "2025-08-24 20:45:02",
        "bing_sent": "2025-08-24 20:05:05",
        "google_indexed": 1,
        "google_indexing_check_date": "2025-08-29"
    }
}

Donde:

Campo Descripción
id ID del enlace
url Enlace
google * Estado de envío a Google
yandex * Estado de envío a Yandex
bing * Estado de envío a Bing
is_external Enlace externo
google_sent Fecha de envío a Google
yandex_sent Fecha de envío a Yandex
bing_sent Fecha de envío a Bing
google_indexed Indexado en Google
google_indexing_check_date Fecha de verificación de indexación en Google

* Posibles estados:

Estado Significado
New Nuevo
Sent Enviado
In the queue En cola de envío
In the process En proceso de envío
Error sending Se produjo un error al enviar
Don't index No indexar
Sent to reindexing Enviado para reindexación
  • Si ocurre un error, se devolverá un objeto JSON con el mensaje de error. Ejemplos de errores:
{
    "success": false,
    "errors":{
        "link": [
            "The link field is required."
        ]
    }
}
{
    "success": false,
    "errors":[
        "Project not found"
    ]
}
{
    "success": false,
    "errors":[
        "URL not found"
    ]
}

También se puede obtener el estado del enlace por ID

Para ello, realice una solicitud GET a /api/v1/link/status/ID

GET https://2index.ninja/api/v1/link/status/ID

La respuesta será la misma que en el caso anterior

Trabajar con fuentes de referencia

Las fuentes de enlaces están disponibles para todo tipo de proyectos y se gestionan de la misma manera. Para la indexación de proyectos de verificación, solo Google está disponible.

Agregar un mapa del sitio

Realizar una solicitud POST a /api/v1/sitemap/add

 POST https://2index.ninja/api/v1/sitemap/add

Parámetros de la solicitud:

Campo Necesariamente Descripción
id del proyecto Identificación del proyecto
mapa del sitio Enlace al mapa del sitio
Google No, siempre que Yandex o Bing Enviar enlaces a Google
Yandex No, siempre que Google o Bing Enviar enlaces a Yandex
Bing No, siempre que Google o Yandex Enviar enlaces a Bing
acceso a Google concedido No Se concedió el acceso a la cuenta de Google
mirar No Supervisar los cambios en el mapa del sitio

Posibles errores:

Error
Error de validación de datos. Falta uno de los campos obligatorios o tiene un valor no válido.
Tarifa no disponible. El plan tarifario del usuario ha expirado.
Proyecto no encontrado. El usuario no posee el proyecto especificado o este no existe.
Error Interno del Servidor

Ejemplos de respuestas:

Adición exitosa del mapa del sitio:

 {
    "success": true,
    "message": "Карта сайта успешно добавлена, мы скачаем её как можно скорее и отправим уведомление по электронной почте после завершения."
}

Error de validación:

 {
    "errors": ["sitemap":["The sitemap field is required."]]
}

Proyecto no encontrado:

 {
    "errors": ["Project not found"]
}

Actualización del estado de seguimiento del mapa del sitio

Realizar una solicitud POST a /api/v1/sitemap/update_watch

 POST https://2index.ninja/api/v1/sitemap/update_watch

Parámetros de la solicitud:

Campo Tipo Necesariamente Descripción
id del proyecto entero Identificación del proyecto
id del mapa del sitio entero ID del mapa del sitio
mirar booleano Indicación de si se deben supervisar los cambios en el mapa del sitio

Posibles errores:

Error
Error de validación de datos. Falta uno de los campos obligatorios o tiene un valor no válido.
No se encontró el proyecto ni la fuente de referencia. El usuario no posee el proyecto especificado o el proyecto o la fuente no existen.
Error Interno del Servidor

Ejemplos de respuestas:

Actualización exitosa del estado de seguimiento:

 {
    "success": true
}

Fuente del enlace no encontrada:

 {
    "errors": ["Link source not found"]
}

Eliminar una fuente de enlace

Realizar una solicitud POST a /api/v1/sitemap/delete

 POST https://2index.ninja/api/v1/sitemap/delete

Parámetros de la solicitud:

Campo Tipo Necesariamente Descripción
id del proyecto entero Identificación del proyecto
id del mapa del sitio entero ID del mapa del sitio

Posibles errores:

Error
Error de validación de datos. Falta uno de los campos obligatorios o tiene un valor no válido.
No se encontró el proyecto ni la fuente de referencia. El usuario no posee el proyecto especificado o el proyecto o la fuente no existen.
Error Interno del Servidor

Ejemplos de respuestas:

Eliminación exitosa del enlace de origen:

 {
    "success": true,
    "message": "Источник ссылок успешно удален"
}

Proyecto no encontrado:

 {
    "errors": ["Project not found"]
}

Lista de fuentes de referencia

Para obtener una lista de fuentes de enlaces agregadas, debe realizar una solicitud POST a https://2index.ninja/api/v1/link_sources

Pase project_id en la solicitud

El resultado se devolverá de la siguiente manera:

 [
    {
        "id": 1247,
        "project_id": 3540,
        "name": "urls.txt",
        "type": "text file",
        "created_at": "2025-01-17T15:51:43.000000Z",
        "processing_date": "2025-01-17T15:51:48.000000Z",
        "has_error": false,
        "error_message": "",
        "status": "success",
        "is_pending": false,
        "is_success": true,
        "total_links": 29585,
        "added_links": 29582,
        "invalid_links": 3,
        "watch": 0,
        "google_access_granted": 0,
        "is_external_links": 1,
        "search_engines": {
            "google": "1"
        }
    },
    {
        "id": 22,
        "project_id": 3540,
        "name": "https://2index.ninja/sitemap.xml",
        "type": "sitemap",
        "created_at": "2025-07-03T14:24:23.000000Z",
        "processing_date":,
        "has_error":,
        "error_message":,
        "status": "pending",
        "is_pending": 1,
        "is_success":,
        "total_links": 0,
        "added_links": 0,
        "invalid_links": 0,
        "watch": 1,
        "google_access_granted": 0,
        "is_external_links": 1,
        "search_engines": {
            "google": 1
        }
    }
]

Dónde

id - id de la fuente del enlace
project_id - id del proyecto
name - el nombre del archivo adjunto o la dirección del mapa del sitio
type - tipo de archivo de origen (archivo de texto o mapa del sitio) - puede ser:
sitemap ,
text file
created_at - fecha de creación
processing_date - fecha de procesamiento
has_error - se produjo un error de procesamiento
error_message - mensaje de error
status - estado - puede ser:
pending (esperando procesamiento),
error (error de procesamiento),
success
is_pending - actualmente en proceso
is_success - procesamiento exitoso
total_links - total de enlaces encontrados
added_links - enlaces añadidos
invalid_links - enlaces no válidos
watch - estado de monitoreo del mapa del sitio
google_access_granted : acceso a la cuenta de Google concedido o no
is_external_links - enlaces externos
search_engines - motores de búsqueda conectados

Ejemplo de implementación en PHP

<?php


/**
 * Clase para interactuar con la API del servicio 2Index.Ninja
 */
class API_2IndexNinja
{
    /**
     * URL del endpoint de la API
     * @var string
     */
    private $url = 'https://2index.ninja/api/v1/';

    /**
     * Token de acceso a la API
     * @var string
     */
    private $access_token;

    /**
     * Constructor de la clase.
     *
     * @param string $access_token Token de acceso para la autorización en la API.
     */
    public function __construct($access_token)
    {
        $this->access_token = $access_token;
    }

    /*
    |--------------------------------------------------------------------------
    | Métodos para trabajar con la cuenta
    |--------------------------------------------------------------------------
    */

    /**
     * Obtiene información sobre la cuenta actual.
     *
     * @return array|null Respuesta decodificada de la API con los datos de la cuenta.
     */
    public function account()
    {
        return $this->make_request('account');
    }

    /*
    |--------------------------------------------------------------------------
    | Métodos para trabajar con proyectos
    |--------------------------------------------------------------------------
    */

    /**
     * Obtiene una lista de todos los proyectos.
     *
     * @return array|null Respuesta decodificada de la API con la lista de proyectos.
     */
    public function projects_list()
    {
        return $this->make_request('project');
    }

    /**
     * Obtiene los datos de un proyecto específico por su ID.
     *
     * @param int $id ID del proyecto.
     * @return array|null Respuesta decodificada de la API con los datos del proyecto.
     */
    public function project($id)
    {
        return $this->make_request('project/' . $id);
    }

    /**
     * Agrega un nuevo proyecto para la indexación de enlaces.
     *
     * @param string $name Nombre del proyecto.
     * @param string $website Sitio web del proyecto.
     * @param bool $for_external_links Destinado a enlaces externos (0 o 1).
     * @param int|null $indexing_speed Velocidad de indexación.
     * @return array|null Respuesta decodificada de la API con los datos del proyecto creado.
     */
    public function add_project($name, $website, $for_external_links = 0, $indexing_speed = null)
    {
        return $this->make_request('project', [
            'name'               => $name,
            'website'            => $website,
            'for_external_links' => $for_external_links,
            'indexing_speed'     => $indexing_speed,
            'type'               => 'indexing',
        ]);
    }

    /**
     * Agrega un nuevo proyecto para la verificación de indexación.
     *
     * @param string $name Nombre del proyecto.
     * @param int|null $checking_speed Velocidad de verificación.
     * @return array|null Respuesta decodificada de la API con los datos del proyecto creado.
     */
    public function add_indexing_check_project($name, $checking_speed = null)
    {
        return $this->make_request('project', [
            'name'           => $name,
            'checking_speed' => $checking_speed,
            'type'           => 'indexing_check',
        ]);
    }

    /**
     * Borra la cola de enlaces de un proyecto.
     *
     * @param int $project_id ID del proyecto.
     * @return array|null Respuesta decodificada de la API.
     */
    public function clear_queue($project_id)
    {
        return $this->make_request('project/' . $project_id . '/clear_queue', true);
    }

    /*
    |--------------------------------------------------------------------------
    | Métodos para trabajar con enlaces
    |--------------------------------------------------------------------------
    */

    /**
     * Agrega enlaces al proyecto especificado.
     *
     * @param int $project_id ID del proyecto.
     * @param array|string $links Array de enlaces o un solo enlace como string.
     * @param bool $google Enviar a Google.
     * @param bool $yandex Enviar a Yandex.
     * @param bool $bing Enviar a Bing.
     * @param bool $google_access_granted Bandera que confirma el acceso a Google.
     * @return array|null Respuesta decodificada de la API.
     */
    public function add_links($project_id, $links, $google, $yandex, $bing, $google_access_granted = false)
    {
        return $this->make_request('link/add', [
            'project_id'            => $project_id,
            'links'                 => $links,
            'google'                => $google,
            'yandex'                => $yandex,
            'bing'                  => $bing,
            'google_access_granted' => $google_access_granted,
        ]);
    }

    /**
     * Agrega enlaces a un proyecto por nombre. Si el proyecto no existe, se creará.
     *
     * @param array|string $links Array de enlaces o un solo enlace como string.
     * @param bool $google Enviar a Google.
     * @param bool $yandex Enviar a Yandex.
     * @param bool $bing Enviar a Bing.
     * @param string $project_name Nombre del proyecto (por defecto 'default').
     * @param bool $google_access_granted Bandera que confirma el acceso a Google.
     * @return array|null Respuesta decodificada de la API.
     */
    public function add_links_simple($links, $google, $yandex, $bing, $project_name = 'default', $google_access_granted = false)
    {
        return $this->make_request('link/add_simple', [
            'project_name'          => $project_name,
            'links'                 => $links,
            'google'                => $google,
            'yandex'                => $yandex,
            'bing'                  => $bing,
            'google_access_granted' => $google_access_granted,
        ]);
    }

    /**
     * Obtiene las fuentes de enlaces para un proyecto.
     *
     * @param int $project_id ID del proyecto.
     * @return array|null Respuesta decodificada de la API.
     */
    public function link_sources($project_id)
    {
        return $this->make_request('link_sources', [
            'project_id' => $project_id
        ]);
    }

    /**
     * Obtiene el estado del enlace especificado
     * Si el mismo enlace fue enviado varias veces, mostrará el estado del último enlace enviado
     *
     * @param int $project_id El ID del proyecto
     * @param string $link Enlace a verificar
     * @return array Estado del enlace
     */
    public function checkLink($project_id, $link)
    {
        return $this->make_request('link/status', [
            'project_id' => $project_id,
            'link' => $link,
        ]);
    }

    /**
     * Obtiene el estado del enlace especificado
     *
     * @param int $link_id ID del enlace
     * @return array Estado del enlace
     */
    public function checkLinkById($link_id)
    {
        return $this->make_request('link/status/' . $link_id);
    }

    /**
     * Reenvía enlaces no indexados
     *
     * Si se pasan enlaces que no se enviaron, también se añadirán a la cola.
     *
     * @param int $project_id ID del proyecto
     * @param int $max_attempts Número máximo de reenvíos de enlaces (de 1 a 10)
     * @param array $links (opcional) Matriz de enlaces que se reenviarán para indexación; si no se pasan enlaces, se reenvían todos los enlaces no indexados del proyecto.
     * @return void
     */
    public function resent_notindexed_links($project_id, $max_attempts, array $links = [])
    {
        return $this->make_request('link/resent_notindexed_links/' . $project_id, [
            'max_attempts' => $max_attempts,
            'links' => $links,
        ]);
    }

    /**
     * Eliminar enlaces del proyecto
     *
     * @param string|array $link
     * @return void
     */
    public function deleteUrls($project_id, $link)
    {
        return $this->make_request('link/delete/' . $project_id, [
            'link' => $link,
        ]);
    }

    /*
    |--------------------------------------------------------------------------
    | Métodos para trabajar con fuentes de enlaces
    |--------------------------------------------------------------------------
    */

    /**
     * Agrega un Sitemap a un proyecto.
     *
     * @param int $project_id ID del proyecto.
     * @param string $sitemap_url URL del archivo Sitemap.
     * @param bool $google Enviar a Google.
     * @param bool $yandex Enviar a Yandex.
     * @param bool $bing Enviar a Bing.
     * @param bool $google_access_granted Bandera que confirma el acceso a Google.
     * @param bool $watch Habilitar el seguimiento de cambios en el Sitemap.
     * @return array|null Respuesta decodificada de la API.
     */
    public function add_sitemap($project_id, $sitemap_url, $google, $yandex, $bing, $google_access_granted = false, $watch = false)
    {
        return $this->make_request('sitemap/add', [
            'project_id'            => $project_id,
            'sitemap'               => $sitemap_url,
            'google'                => $google,
            'yandex'                => $yandex,
            'bing'                  => $bing,
            'google_access_granted' => $google_access_granted,
            'watch'                 => $watch,
        ]);
    }

    /**
     * Habilita o deshabilita el seguimiento de cambios para un Sitemap.
     *
     * @param int $project_id ID del proyecto.
     * @param int $sitemap_id ID del archivo Sitemap.
     * @param bool $watch Nuevo estado de seguimiento (true - habilitar, false - deshabilitar).
     * @return array|null Respuesta decodificada de la API.
     */
    public function update_sitemap_watch($project_id, $sitemap_id, $watch)
    {
        return $this->make_request('sitemap/update_watch', [
            'project_id' => $project_id,
            'sitemap_id' => $sitemap_id,
            'watch'      => $watch,
        ]);
    }

    /**
     * Elimina un Sitemap de un proyecto.
     *
     * @param int $project_id ID del proyecto.
     * @param int $sitemap_id ID del archivo Sitemap a eliminar.
     * @return array|null Respuesta decodificada de la API.
     */
    public function sitemap_delete($project_id, $sitemap_id)
    {
        return $this->make_request('sitemap/delete', [
            'project_id' => $project_id,
            'sitemap_id' => $sitemap_id,
        ]);
    }

    /**
     * Realiza una solicitud a la API.
     *
     * @param string $endpoint Endpoint de la API a llamar.
     * @param array|true $post_data Datos para la solicitud POST. Si es true, se envía un POST vacío.
     * @return array|null Respuesta JSON decodificada de la API o null en caso de error.
     */
    private function make_request($endpoint, $post_data = [])
    {
        $ch = curl_init($this->url . $endpoint);

        if ($post_data === true) {
            curl_setopt($ch, CURLOPT_POST, 1);
        } elseif ($post_data) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
        }

        curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . $this->access_token]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);

        // Especifica el user-agent, es necesario si aparecen errores 403
        // curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36');

        $result = curl_exec($ch);
        curl_close($ch);

        return json_decode($result, 1);
    }
}