> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ovac.councilbox.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ovac.councilbox.com/_mcp/server.

# Login

POST https://api.ovac.pre.councilbox.com/graphql/login
Content-Type: application/json

# Login (`mutation`)

Este método realiza la autenticación de un usuario en el sistema mediante sus credenciales (correo electrónico y contraseña). Al completarse con éxito, genera un token de acceso principal (`token`) y un token de renovación (`refreshToken`) necesarios para consumir el resto de endpoints protegidos de la API.

### Detalles de la Solicitud

- **Método HTTP:** `POST`
    
- **URL:** `https://api.ovac.pre.councilbox.com/graphql`
    

### Cabeceras (Headers)

| **Key** | **Value** | **Requerido** | **Descripción** |
| --- | --- | --- | --- |
| **Content-Type** | application/json | Sí | Especifica el formato JSON para el cuerpo de la petición. |
| **x-jwt-token** | {{token}} | No | No es necesario para el login inicial, se utiliza en llamadas posteriores. |

## Referencia de la API

### Parámetros de Entrada (Variables)

| **Campo** | **Tipo** | **Requerido** | **Descripción** |
| --- | --- | --- | --- |
| **email** | String! | SI | Correo electrónico registrado de la cuenta de usuario. |
| **password** | String! | SI | Contraseña asociada a la cuenta. |

### Campos de Respuesta (Payload)

La mutación devuelve un objeto `login` con los elementos necesarios para la gestión de la sesión:

| Campo | Tipo | Descripción |
| --- | --- | --- |
| **token** | String | oken JWT primario que debe enviarse en la cabecera `x-jwt-token` en las siguientes consultas. |
| **refreshToken** | String | Token persistente utilizado para solicitar un nuevo token de acceso cuando el actual expire. |
| **expires** | Integer | Tiempo de vida útil del token expresado en segundos (ej. `21600` equivale a 6 horas). |

## Ejemplos de Código y Peticiones

### 1\. Mutación GraphQL

``` graphql
mutation Login($email: String!, $password: String!) {
    login(email: $email, password: $password) {
        token
        refreshToken
        expires
    }
}

 ```

### 2\. Variables de la Petición (JSON Payload)

``` json
{
    "email": "ejemplo@dominio.com",
    "password": "contraseña123"
}

 ```

### 3\. Ejemplo de comando cURL

``` bash
curl --location --globoff "https://api.ovac.pre.councilbox.com/graphql" \
--header "Content-Type: application/json" \
--data '{"query":"mutation ($email: String!, $password: String!) { login(email: $email, password: $password) { token refreshToken expires } }","variables":{"email":"ejemplo@dominio.com","password":"contraseña123"}}'

 ```

### 4\. Respuesta Esperada (200 OK)

``` json
{
    "data": {
        "login": {
            "token": "eyJhbGciOiJIUzI1NiR5cCI6IkpXVCJ9.eyJqdGkiOiJkZTc0ZTc5YS1kMzZhLTRiOTYtYWEzNC03NmViOGM5ODlkOWEiLCJ1c2VyX2lkIjozNDc2LCJ0b2tlbl90eXBlIjoidXNlciIsImlhdCI6MTc3NjM1NzE5MH0.AHiUq8QwxSPnuQD9FngbS8FZ0Jf3v81AnXdXsJWjXRo",
            "refreshToken": "eyJhbGciOiJIUz1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MzQ3Niwic2Vzc2lvbklkIjoiZGU3NGU3OWEtZDM2YS00Yjk2LWFhMzQtNzZlYjhjOTg5ZDlhIiwiaWF0IjoxNzc2MzU3MTkwfQ.ddJqC8Jd20qYsm6dR8dhb1YkBV9XSsvrTGX2CzGXepM",
            "expires": 21600
        }
    }
}

 ```

> **Nota OpenAPI/Fern:** esta operación GraphQL se documenta como `/graphql/login` para que Fern pueda mostrarla como operación independiente. La ruta técnica real de ejecución es `POST /graphql`.


Reference: https://docs.ovac.councilbox.com/metodos-api/00-authentication/login

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: ovac
  version: 1.0.0
paths:
  /graphql/login:
    post:
      operationId: login
      summary: Login
      description: >
        # Login (`mutation`)


        Este método realiza la autenticación de un usuario en el sistema
        mediante sus credenciales (correo electrónico y contraseña). Al
        completarse con éxito, genera un token de acceso principal (`token`) y
        un token de renovación (`refreshToken`) necesarios para consumir el
        resto de endpoints protegidos de la API.


        ### Detalles de la Solicitud


        - **Método HTTP:** `POST`
            
        - **URL:** `https://api.ovac.pre.councilbox.com/graphql`
            

        ### Cabeceras (Headers)


        | **Key** | **Value** | **Requerido** | **Descripción** |

        | --- | --- | --- | --- |

        | **Content-Type** | application/json | Sí | Especifica el formato JSON
        para el cuerpo de la petición. |

        | **x-jwt-token** | {{token}} | No | No es necesario para el login
        inicial, se utiliza en llamadas posteriores. |


        ## Referencia de la API


        ### Parámetros de Entrada (Variables)


        | **Campo** | **Tipo** | **Requerido** | **Descripción** |

        | --- | --- | --- | --- |

        | **email** | String! | SI | Correo electrónico registrado de la cuenta
        de usuario. |

        | **password** | String! | SI | Contraseña asociada a la cuenta. |


        ### Campos de Respuesta (Payload)


        La mutación devuelve un objeto `login` con los elementos necesarios para
        la gestión de la sesión:


        | Campo | Tipo | Descripción |

        | --- | --- | --- |

        | **token** | String | oken JWT primario que debe enviarse en la
        cabecera `x-jwt-token` en las siguientes consultas. |

        | **refreshToken** | String | Token persistente utilizado para solicitar
        un nuevo token de acceso cuando el actual expire. |

        | **expires** | Integer | Tiempo de vida útil del token expresado en
        segundos (ej. `21600` equivale a 6 horas). |


        ## Ejemplos de Código y Peticiones


        ### 1\. Mutación GraphQL


        ``` graphql

        mutation Login($email: String!, $password: String!) {
            login(email: $email, password: $password) {
                token
                refreshToken
                expires
            }
        }

         ```

        ### 2\. Variables de la Petición (JSON Payload)


        ``` json

        {
            "email": "ejemplo@dominio.com",
            "password": "contraseña123"
        }

         ```

        ### 3\. Ejemplo de comando cURL


        ``` bash

        curl --location --globoff "https://api.ovac.pre.councilbox.com/graphql"
        \

        --header "Content-Type: application/json" \

        --data '{"query":"mutation ($email: String!, $password: String!) {
        login(email: $email, password: $password) { token refreshToken expires }
        }","variables":{"email":"ejemplo@dominio.com","password":"contraseña123"}}'

         ```

        ### 4\. Respuesta Esperada (200 OK)


        ``` json

        {
            "data": {
                "login": {
                    "token": "eyJhbGciOiJIUzI1NiR5cCI6IkpXVCJ9.eyJqdGkiOiJkZTc0ZTc5YS1kMzZhLTRiOTYtYWEzNC03NmViOGM5ODlkOWEiLCJ1c2VyX2lkIjozNDc2LCJ0b2tlbl90eXBlIjoidXNlciIsImlhdCI6MTc3NjM1NzE5MH0.AHiUq8QwxSPnuQD9FngbS8FZ0Jf3v81AnXdXsJWjXRo",
                    "refreshToken": "eyJhbGciOiJIUz1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MzQ3Niwic2Vzc2lvbklkIjoiZGU3NGU3OWEtZDM2YS00Yjk2LWFhMzQtNzZlYjhjOTg5ZDlhIiwiaWF0IjoxNzc2MzU3MTkwfQ.ddJqC8Jd20qYsm6dR8dhb1YkBV9XSsvrTGX2CzGXepM",
                    "expires": 21600
                }
            }
        }

         ```

        > **Nota OpenAPI/Fern:** esta operación GraphQL se documenta como
        `/graphql/login` para que Fern pueda mostrarla como operación
        independiente. La ruta técnica real de ejecución es `POST /graphql`.
      tags:
        - subpackage_00Authentication
      responses:
        '200':
          description: >-
            Successful response. GraphQL business errors may be returned inside
            the JSON `errors` field while transport status remains HTTP 200.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/00 - Authentication_login_Response_200'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                query:
                  type: string
                  description: GraphQL operation
                variables:
                  $ref: >-
                    #/components/schemas/GraphqlLoginPostRequestBodyContentApplicationJsonSchemaVariables
                  description: GraphQL variables
              required:
                - query
servers:
  - url: https://api.ovac.pre.councilbox.com
    description: Pre-production
  - url: https://api.ovac.councilbox.com
    description: Production
components:
  schemas:
    GraphqlLoginPostRequestBodyContentApplicationJsonSchemaVariables:
      type: object
      properties: {}
      description: GraphQL variables
      title: GraphqlLoginPostRequestBodyContentApplicationJsonSchemaVariables
    00 - Authentication_login_Response_200:
      type: object
      properties: {}
      title: 00 - Authentication_login_Response_200

```

## Examples



**Request**

```json
{
  "query": "mutation (\n    $email: String!,\n    $password: String!\n    ){\n    login(\n        email: $email, \n        password: $password)\n        {\n            token\n            refreshToken\n            expires\n        }\n    }",
  "variables": {
    "email": "{{user_email}}",
    "password": "{{user_password}}"
  }
}
```

**Response**

```json
{
  "data": {
    "login": {
      "token": "eyJhbGciOiJIUzI1sInR5cCI6IkpXVCJ9.eyJqdGkiOiIxOTU4ZGIxZS00ZTg2LTQwMDMtODNjZi0xYzA4NDEwODY1ODkiLCJ1c2VyX2lkIjozNDc2LCJ0b2tlbl90eXBlIjoidXNlciIsImlhdCI6MTc3OTI5MzAwMn0.0M-MaccgBi0SUfNRkvE-CYmEDdxHeHRQkEwfz3P0xjk",
      "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MzQ3Niwic2Vzc2lvbklkIjoiMTk1OGRiMWUtNGU4Ni00MDAzLTgzY2YtMWMwODQxMDg2NTg5IiwiaWF0IjoxNzc5MjkzMDAyfQ.yZfPXRX3rSyQtMQcjXTVjwkA3p3JCMDhV3xbYmxa6YU",
      "expires": 21600
    }
  }
}
```

**SDK Code**

```python Login
import requests

url = "https://api.ovac.pre.councilbox.com/graphql/login"

payload = {
    "query": "mutation (
    $email: String!,
    $password: String!
    ){
    login(
        email: $email, 
        password: $password)
        {
            token
            refreshToken
            expires
        }
    }",
    "variables": {
        "email": "{{user_email}}",
        "password": "{{user_password}}"
    }
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Login
const url = 'https://api.ovac.pre.councilbox.com/graphql/login';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: '{"query":"mutation (\n    $email: String!,\n    $password: String!\n    ){\n    login(\n        email: $email, \n        password: $password)\n        {\n            token\n            refreshToken\n            expires\n        }\n    }","variables":{"email":"{{user_email}}","password":"{{user_password}}"}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Login
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.ovac.pre.councilbox.com/graphql/login"

	payload := strings.NewReader("{\n  \"query\": \"mutation (\\n    $email: String!,\\n    $password: String!\\n    ){\\n    login(\\n        email: $email, \\n        password: $password)\\n        {\\n            token\\n            refreshToken\\n            expires\\n        }\\n    }\",\n  \"variables\": {\n    \"email\": \"{{user_email}}\",\n    \"password\": \"{{user_password}}\"\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Login
require 'uri'
require 'net/http'

url = URI("https://api.ovac.pre.councilbox.com/graphql/login")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n  \"query\": \"mutation (\\n    $email: String!,\\n    $password: String!\\n    ){\\n    login(\\n        email: $email, \\n        password: $password)\\n        {\\n            token\\n            refreshToken\\n            expires\\n        }\\n    }\",\n  \"variables\": {\n    \"email\": \"{{user_email}}\",\n    \"password\": \"{{user_password}}\"\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java Login
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.ovac.pre.councilbox.com/graphql/login")
  .header("Content-Type", "application/json")
  .body("{\n  \"query\": \"mutation (\\n    $email: String!,\\n    $password: String!\\n    ){\\n    login(\\n        email: $email, \\n        password: $password)\\n        {\\n            token\\n            refreshToken\\n            expires\\n        }\\n    }\",\n  \"variables\": {\n    \"email\": \"{{user_email}}\",\n    \"password\": \"{{user_password}}\"\n  }\n}")
  .asString();
```

```php Login
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.ovac.pre.councilbox.com/graphql/login', [
  'body' => '{
  "query": "mutation (\\n    $email: String!,\\n    $password: String!\\n    ){\\n    login(\\n        email: $email, \\n        password: $password)\\n        {\\n            token\\n            refreshToken\\n            expires\\n        }\\n    }",
  "variables": {
    "email": "{{user_email}}",
    "password": "{{user_password}}"
  }
}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Login
using RestSharp;

var client = new RestClient("https://api.ovac.pre.councilbox.com/graphql/login");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"query\": \"mutation (\\n    $email: String!,\\n    $password: String!\\n    ){\\n    login(\\n        email: $email, \\n        password: $password)\\n        {\\n            token\\n            refreshToken\\n            expires\\n        }\\n    }\",\n  \"variables\": {\n    \"email\": \"{{user_email}}\",\n    \"password\": \"{{user_password}}\"\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Login
import Foundation

let headers = ["Content-Type": "application/json"]
let parameters = [
  "query": "mutation (
    $email: String!,
    $password: String!
    ){
    login(
        email: $email, 
        password: $password)
        {
            token
            refreshToken
            expires
        }
    }",
  "variables": [
    "email": "{{user_email}}",
    "password": "{{user_password}}"
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.ovac.pre.councilbox.com/graphql/login")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```