> For the complete documentation index, see [llms.txt](https://docs.exoclick.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.exoclick.com/api/es/api-publica-de-exoclick/api-manual-php-examples.md).

# Ejemplos en PHP

## Resumen

Los ejemplos de código de esta sección usan todas las siguientes clases.

La clase Request usa **cURL** para realizar las solicitudes a la API.

La clase Response contiene la respuesta de la API y la información del código de estado devuelto.

<details>

<summary>Clases Request y Response</summary>

```php
class Request {

        /**
         * @var resource
         */
        protected $_request;

        /**
         * @var integer
         */
        protected $_method;

        /**
         * @var string
         */
        protected $_url;

        /**
         * @var array
         */
        protected $_headers = array(
            'Content-type: application/json'
        );

        /**
         * @var string|array
         */
        protected $_params;

        /**
         * @var object Response
         */
        protected $_reponse;

        /**
         * Constructor
         *
         * @param   string      $url
         * @param   string      $method
         * @param   array       $params
         */
        public function __construct($url, $method, $params = array()) {

            $this->_url = $url;

            // Establecer el método
            $this->_method = $method;

            // Establecer los parámetros
            $this->_params = $params;
        }

        /**
         * Determinar el método Request
         *
         * @param   string  $method
         */
        private function setMethod() {

            switch($this->_method) {
                case 'GET':
                    break;
                case 'POST':
                    curl_setopt($this->_request, CURLOPT_POST, 1);
                    break;
                case 'PUT':
                    curl_setopt($this->_request, CURLOPT_CUSTOMREQUEST, 'PUT');
                    break;
                case 'DELETE':
                    curl_setopt($this->_request, CURLOPT_CUSTOMREQUEST, 'DELETE');
                    break;
            }
        }

        /**
         * Añadir encabezado de autorización
         *
         * @param   string  $type
         * @param   string  $token
         */
        public function setAuthorizationHeader($type, $token) {

            $authorization = $type . ' ' . $token;

            $this->_headers[] = 'Authorization: ' . $authorization;
        }

        /**
         * Añadir cuerpo a la solicitud
         */
        private function addBody() {

            if($this->_method != 'GET' && empty($this->_params) == false) {

                if(is_array($this->_params)) {
                    // Codificar el array en JSON
                    $this->_params = json_encode($this->_params);
                }

                curl_setopt($this->_request, CURLOPT_POSTFIELDS, $this->_params);

                // Añadir un encabezado content-length
                $this->_headers[] = 'Content-length: ' . strlen($this->_params);
            }
        }

        /**
         * Añadir una cadena de consulta a la solicitud
         */
        private function addQueryString() {

            if($this->_method == 'GET' && is_array($this->_params) && count($this->_params) > 0) {

                $query_string = '?';

                foreach($this->_params as $param => $value) {

                    $query_string = $query_string . $param . '=' . $value . '&';
                }

                trim($query_string, '&');

                $this->_url = $this->_url . $query_string;
            }
            else {

                if(is_array($this->_params) && count($this->_params) > 0 && strpos($this->_url, '{') !== false) {
                    // Hacer coincidir los parámetros con la URL
                    foreach($this->_params as $param => $value) {
                        $this->_url = preg_replace('/{' . $param . '}/', $value, $this->_url);
                    }
                }
            }
        }

        /**
         * Enviar la solicitud
         */
        public function send() {

            // Inicializar la solicitud cURL
            $this->_request = curl_init();

            // Devolver la respuesta como una cadena
            curl_setopt($this->_request, CURLOPT_RETURNTRANSFER, 1);

            // Añadir una cadena de consulta
            $this->addQueryString();

            // Establecer la URL
            curl_setopt($this->_request, CURLOPT_URL, $this->_url);

            // Establecer el método de solicitud
            $this->setMethod();

            // Añadir un cuerpo
            $this->addBody();

            if(empty($this->_headers) == false) {
                // Establecer los encabezados
                curl_setopt($this->_request, CURLOPT_HTTPHEADER, $this->_headers);
            }

            // Desactivar comprobaciones SSL
            curl_setopt($this->_request, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($this->_request, CURLOPT_SSL_VERIFYHOST, false);

            // Enviar la solicitud y almacenar el cuerpo
            $this->_response = new Response(curl_exec($this->_request));

            // Establecer el código de estado
            $this->_response->setStatusCode(curl_getinfo($this->_request, CURLINFO_HTTP_CODE));

            // Cerrar la conexión
            curl_close($this->_request);
        }

        /**
         * Obtener la respuesta
         *
         * @return object
         */
        public function getResponse() {

            return $this->_response;
        }
    }

    class Response {

        /**
         * @var array
         */
        protected $_reason_phrases = array(
            // Informativas 1xx
            100 => "Continuar",
            101 => "Cambiando protocolos",

            // Correctas 2xx
            200 => "OK",
            201 => "Creado",
            202 => "Aceptado",
            203 => "Información no autorizada",
            204 => "Sin contenido",
            205 => "Restablecer contenido",
            206 => "Contenido parcial",

            // Redirección 3xx
            300 => "Múltiples opciones",
            301 => "Movido permanentemente",
            302 => "Encontrado",
            303 => "Ver otro",
            304 => "No modificado",
            305 => "Usar proxy",
            306 => "(Sin uso)",
            307 => "Redirección temporal",

            // Error del cliente 4xx
            400 => "Solicitud incorrecta",
            401 => "No autorizado",
            402 => "Pago requerido",
            403 => "Prohibido",
            404 => "No encontrado",
            405 => "Método no permitido",
            406 => "No aceptable",
            407 => "Se requiere autenticación del proxy",
            408 => "Tiempo de espera de la solicitud agotado",
            409 => "Conflicto",
            410 => "Desaparecido",
            411 => "Longitud requerida",
            412 => "Falló la condición previa",
            413 => "Entidad de solicitud demasiado grande",
            414 => "URI de solicitud demasiado larga",
            415 => "Tipo de medio no compatible",
            416 => "El rango solicitado no es satisfacible",
            417 => "Falló la expectativa",

            // Error del servidor 5xx
            500 => "Error interno del servidor",
            501 => "No implementado",
            502 => "Puerta de enlace incorrecta",
            503 => "Servicio no disponible",
            504 => "Tiempo de espera de la puerta de enlace agotado",
            505 => "Versión de HTTP no compatible"
        );

        /**
         * @var integer
         */
        protected $_status_code;

        /**
         * @var string
         */
        protected $_body;

        /**
         * Constructor
         *
         * @param   string      $body
         */
        public function __construct($body) {

            $this->_body = $body;
        }

        /**
         * Constructor
         *
         * @param   string      $status_code
         */
        public function setStatusCode($status_code) {

            $this->_status_code = $status_code;
        }

        /**
         * Obtener el código de estado
         *
         * @return  integer
         */
        public function getStatusCode() {

            return $this->_status_code;
        }

        /**
         * Obtener el cuerpo
         *
         * @return  string
         */
        public function getBody() {

            return $this->_body;
        }

        /**
         * Obtener el cuerpo decodificado en JSON
         *
         * @return  object|null
         */
        public function getBodyDecoded() {

            return json_decode($this->_body);
        }

        /**
         * Obtener la frase de motivo
         *
         * @return string|boolean
         */
        public function getReasonPhrase() {

            if(array_key_exists($this->_status_code, $this->_reason_phrases)) {

                return $this->_reason_phrases[$this->_status_code];
            }
            else {

                return false;
            }
        }
    }
```

</details>

## Iniciar sesión

Hay dos opciones para solicitar la **inicio de sesión** ruta:

* con nombre de usuario y contraseña
* con token de API (token de acceso)

Ejemplo de inicio de sesión con parámetros de nombre de usuario y contraseña.

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/login';

    $params = array(
        'username'  => 'sample_username',
        'password'  => 'sample_password'
    );

    // Crear un nuevo objeto Request
    $request = new Request($url, 'POST', $params);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto Response
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        // Recuperar los detalles del token de sesión
        $token = $response->getBodyDecoded();

        print_r($token);
    }
    else {

        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody() . PHP_EOL;
    }
?>
```

### Ejemplo de inicio de sesión con token de API (token de acceso)

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/login';

    $params = array(
            'api_token'  => 'sample_token_2bb447abb71b69368901a....'
        );

    // Crear un nuevo objeto Request
    $request = new Request($url, 'POST', $params);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto Response
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        // Recuperar los detalles del token de sesión
        $token = $response->getBodyDecoded();

        print_r($token);
    }
    else {

        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody() . PHP_EOL;
    }
?>
```

## Autenticación

Cada solicitud a contenido relacionado con el usuario requiere un **Autorización** encabezado que se establezca, con el valor que contenga el tipo de token y el token de sesión recibido de la solicitud de inicio de sesión de la API.

Un **/login** la solicitud a la API devolverá el siguiente payload JSON.

```json
{
  "token": "",
  "type": "",
  "expires_in": 0
}
```

El **Token de sesión** debe incluirse en todas las solicitudes posteriores de contenido relacionado con el usuario a la API.

El **type** debe anteponerse al token, separado por un solo espacio.

```
Bearer 4e63518d383d8fcaefb516fe708b893727463031
```

El **expires\_in** es el tiempo en segundos durante el cual el token será válido. Cuando este tiempo expire, será necesario obtener un nuevo token mediante la solicitud /login.

### Ejemplo de obtención y configuración del encabezado de autorización con nombre de usuario y contraseña

```php
<?php

    // Incluir las clases Request y Response

    // Inicio de sesión
    $url = 'https://api.example.com/v2/login';

    $params = array(
        'username'  => 'sample_username',
        'password'  => 'sample_password'
    );

    // Crear un nuevo objeto Request
    $request = new Request($url, 'POST', $params);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto Response
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        // Recuperar los detalles del token de sesión
        $token = $response->getBodyDecoded();

        // Obtener campañas
        $url = 'https://api.example.com/v2/campaigns';

        // Crear un nuevo objeto Request
        $request = new Request($url, 'GET');

        // Establecer el encabezado de autorización
        $request->setAuthorizationHeader($token->type, $token->token);

        // Enviar la solicitud
        $request->send();

        // Obtener el objeto Response
        $response = $request->getResponse();

        if($response->getStatusCode() == 200) {

            // Recuperar las campañas
            $campaigns = $response->getBodyDecoded();

            foreach($campaigns->result as $campaign) {
                // Mostrar los nombres de las campañas
                echo $campaign->name . PHP_EOL;
            }
        }
        else {
            // Error en la solicitud de campañas
            echo $response->getStatusCode() . PHP_EOL;
            echo $response->getReasonPhrase() . PHP_EOL;
            echo $response->getBody();
        }
    }
    else {
        // Inicio de sesión no válido
        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody();
    }
?>
```

### Ejemplo de obtención y configuración del encabezado de autorización con token de API

```php
<?php

    // Incluir las clases Request y Response

    // Inicio de sesión
    $url = 'https://api.example.com/v2/login';

    $params = array(
        'api_token'  => 'sample_token_2bb447abb71b69368901a....'
    );

    ...

?>
```

## Colecciones

El siguiente es un ejemplo de una solicitud para obtener la **navegadores** colección.

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/collections/browsers';

    // Crear un nuevo objeto Request
    $request = new Request($url, 'GET');

    // Establecer el encabezado de autorización obtenido de la solicitud de inicio de sesión anterior
    $request->setAuthorizationHeader($token->type, $token->token);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto Response
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        $browsers = $response->getBodyDecoded();

        foreach($browsers as $browser) {

            echo $browser->id . ': ' . $browser->name . PHP_EOL;
        }
    }
    else {
        // Colección no encontrada
        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody();
    }
?>
```

## Estadísticas

El siguiente es un ejemplo de una solicitud del anunciante para **statistics/a/date**.

En caso de **additional\_group\_by** se defina un valor, la solicitud se agrupará por el campo principal de la ruta y el/los adicional(es).

### Ejemplo de estadísticas por fecha filtradas por el ID de campaña 1234.

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/statistics/a/date';

    // Especificar el id de campaña
    $params = array(
       'campaignid'  => 1234
    );

    $request = new Request($url, 'GET', $params);

    // Establecer el encabezado de autorización, obtenido de la solicitud de inicio de sesión anterior
    $request->setAuthorizationHeader($token->type, $token->token);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto de respuesta
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        $statistics = $response->getBodyDecoded();

        foreach($statistics->result as $statistic) {

            echo $statistic->ddate . ': ' . $statistic->value . PHP_EOL;
        }
    }
    else {
        // Estadísticas de campaña no encontradas
        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody();
    }
?>
```

### Ejemplo de estadísticas por fecha con agrupación adicional por campaña.

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/statistics/a/date';

    // Especificar el id de campaña
    $params = array(
       'additional_group_by'  => 'campaign'
    );

    $request = new Request($url, 'GET', $params);

    // Establecer el encabezado de autorización, obtenido de la solicitud de inicio de sesión anterior
    $request->setAuthorizationHeader($token->type, $token->token);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto de respuesta
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        $statistics = $response->getBodyDecoded();

        foreach($statistics->result as $statistic) {
            echo $statistic->ddate . ' - ' . $statistic->idcampaign . ': ' . $statistic->value . PHP_EOL;
        }
    }
    else {
        // Estadísticas de campaña no encontradas
        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody();
    }
?>
```

post /statistics/a/global

Obtener estadísticas globales del anunciante

### Ejemplo 1 de estadísticas globales

Ejemplo de solicitud de estadísticas globales.

Solo el `group_by` parámetro es obligatorio. Los valores predeterminados de los demás parámetros se pueden encontrar [aquí](https://api.exoclick.com/v2/docs/#!/47statistics/post_statistics_a_global).

Tenga en cuenta que las rutas de estadísticas globales (`statistics/a/global`, `statistics/p/global`) tienen un formato de parámetros diferente.

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/statistics/a/global';

    // Especificar el group_by
    $params = [
        "group_by" => ["date"]
    ];

    $request = new Request($url, 'POST', $params);

    // Establecer el encabezado de autorización, obtenido de la solicitud de inicio de sesión anterior
    $request->setAuthorizationHeader($token->type, $token->token);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto de respuesta
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        $statistics = $response->getBodyDecoded();

        foreach($statistics->result as $statistic) {
            echo 'Fecha: ' . $statistic->group_by->date->date . ' -  Impresiones: ' . $statistic->impressions .' - Costo: ' .  $statistic->cost . PHP_EOL;
        }
    }
    else {
        // Estadísticas de campaña no encontradas
        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody();
    }
?>
```

### Ejemplo 2 de estadísticas globales

Obtener estadísticas por fecha incluyendo totales sumados.

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/statistics/a/global';

    // Especificar el id de campaña
    $params = [
        "filter" => [
            "date_from" => "2019-01-10",
            "date_to" => "2019-01-31",
        ],
        "totals" => 1,
        "group_by" => ["date"]
    ];

    $request = new Request($url, 'POST', $params);

    // Establecer el encabezado de autorización, obtenido de la solicitud de inicio de sesión anterior
    $request->setAuthorizationHeader($token->type, $token->token);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto de respuesta
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        $statistics = $response->getBodyDecoded();

        foreach($statistics->result as $statistic) {
            echo 'Fecha: ' . $statistic->group_by->date->date . ' -  Impresiones: ' . $statistic->impressions .' - Costo: ' .  $statistic->cost . PHP_EOL;
        }

        echo 'Costo total:' . $statistics->result_total->cost . PHP_EOL;
    }
    else {
        // Estadísticas de campaña no encontradas
        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody();
    }
?>
```

### Ejemplo 3 de estadísticas globales

Obtener estadísticas por campaña y país filtradas por una fecha específica ordenadas por impresiones.

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/statistics/a/global';

    $params = [
        "filter" => [
            "date_from" => "2019-01-30",
            "date_to" => "2019-01-30",
        ],
        "group_by" => ["country_iso", "campaign_id"],
        "order_by" => [
            ["field" => "impressions", "order" => "desc"]
        ]
    ];


    $request = new Request($url, 'POST', $params);

    // Establecer el encabezado de autorización, obtenido de la solicitud de inicio de sesión anterior
    $request->setAuthorizationHeader($token->type, $token->token);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto de respuesta
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        $statistics = $response->getBodyDecoded();

        foreach($statistics->result as $statistic) {
            echo 'País: ' . $statistic->group_by->country_iso->country_iso . ' -  ID de campaña: ' . $statistic->group_by->campaign_id->id .' - Costo: ' .  $statistic->cost . PHP_EOL;
        }
    }
    else {
        // Estadísticas de campaña no encontradas
        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody();
    }
?>
```

### Ejemplo 4 de estadísticas globales

Obtener estadísticas del editor por zona y país filtradas por un sistema operativo específico.

```php
<?php

    // Incluir las clases Request y Response

    $url = 'https://api.example.com/v2/statistics/p/global';

    $params = [
        "filter" => [
            "date_from" => "2019-01-30",
            "date_to" => "2019-01-30",
            "operating_system_id" => [11, 12]
        ],
        "group_by" => ["zone_id", "country_iso"]
    ];


    $request = new Request($url, 'POST', $params);

    // Establecer el encabezado de autorización, obtenido de la solicitud de inicio de sesión anterior
    $request->setAuthorizationHeader($token->type, $token->token);

    // Enviar la solicitud
    $request->send();

    // Obtener el objeto de respuesta
    $response = $request->getResponse();

    if($response->getStatusCode() == 200) {

        $statistics = $response->getBodyDecoded();

        foreach($statistics->result as $statistic) {
            echo ' ID de zona:' . $statistic->group_by->zone_id->id . ' - País: ' . $statistic->group_by->country_iso->country_iso .' - Ingresos: ' .  $statistic->revenue . PHP_EOL;
        }
    }
    else {
        // Estadísticas de campaña no encontradas
        echo $response->getStatusCode() . PHP_EOL;
        echo $response->getReasonPhrase() . PHP_EOL;
        echo $response->getBody();
    }
?>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.exoclick.com/api/es/api-publica-de-exoclick/api-manual-php-examples.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
