# Integrations

### Getting an authentication token

To integrate with any endpoint in Codenull you will need a token to authenticate. First you must to generate an API\_KEY from the application.\
\
Go to  `Designer > Integrations > API Keys`

<figure><img src="/files/b2QNN4yqNIEEISrcB6uB" alt=""><figcaption></figcaption></figure>

From this section you can generate one or more API keys for the application. Each generated API key returns:

* `clientId`: unique identifier for this integration.
* `apiKey`: secret value used to request an authentication token.

The `apiKey` is shown only once when it is generated. Store it securely. Codenull only stores a hash of the API key and it cannot be retrieved later.

You can generate multiple API keys for the same application, for example one per external integration. You can also delete an API key to revoke access for that integration.

To request a token, call:

```json
//request params
{
  "url": "https://MY_APPLICATION_DOMAIN/api/auth/token",
  "method": "POST",
  "body": {
    "clientId": "YOUR_GENERATED_CLIENT_ID",
    "apiKey": "YOUR_GENERATED_API_KEY"
  }
}

// response
{
    "access_token": "xxxxxxxxxxxxxxx", //token to be used.
    "expires_in": 86400, //time in seconds
    "token_type": "Bearer"
}
```

{% hint style="warning" %}
Since API version \`2.10.0\`, \`/api/auth/token\` no longer accepts Auth0 \`client\_id\` and \`client\_secret\` from external clients. Integrations must use the \`clientId\` and \`apiKey\` generated from the application Designer.
{% endhint %}

### Consuming a Codenull enpoint

{% tabs %}
{% tab title="Node.JS (axios)" %}

```javascript
var axios = require('axios');
var data = JSON.stringify({
  "operationName": "updateProducto",
  "variables": {
    "Id": "9999",
    "data": {
      "CalcularImpuestos": false,
      "CategoriaId": "2",
      "Codigo": "B- Frutal Mango 500ML",
      "Costo": 2000,
      "DescuentoEmpleadoAplicable": false,
      "Facturable": true,
      "MostrarEnInventario": true,
      "Id": "24",
      "Nombre": "FRUTAL MANGO 500ML",
      "PosClientId": "0d3ZGanGSO6NxXgx",
      "Precio": 3000,
      "SincronizacionFacturaId": "927",
      "Sincronizado": true,
      "SumarImpuestosAlPrecio": false,
      "GastoFijo": false,
      "Combos__ProductoPadreId": []
    }
  },
  "query": "mutation updateProducto($Id: ID!, $data: ProductoInput) {\n  updateProducto(Id: $Id, data: $data)\n}"
});

var config = {
  method: 'post',
  url: 'https://MY_APPLICATION_DOMAIN/graphql',
  headers: { 
    'authorization': 'Bearer TOKEN_RECEIVED_ABOVE_xxxxxxx',  
    'content-type': 'application/json',
    'x-userid': '4' //pass this user id in case you need to associate the operation to a specific user
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

```

{% endtab %}

{% tab title="CURL" %}

```shell
curl --location --request POST 'https://MY_APPLICATION_DOMAIN/graphql' \
--header 'authorization: Bearer TOKEN_RECEIVED_ABOVE_xxxxxxxxxx' \
--header 'content-type: application/json' \
--header 'x-userid: 4' \
--data-raw '{"operationName":"updateProducto","variables":{"Id":"24","data":{"CalcularImpuestos":false,"CategoriaId":"2","Codigo":"B- Frutal Mango 500ML","Costo":2000,"DescuentoEmpleadoAplicable":false,"Facturable":true,"MostrarEnInventario":true,"Id":"24","Nombre":"FRUTAL MANGO 500ML","PosClientId":"0d3ZGanGSO6NxXgx","Precio":3000,"SincronizacionFacturaId":"927","Sincronizado":true,"SumarImpuestosAlPrecio":false,"GastoFijo":false,"Combos__ProductoPadreId":[]}},"query":"mutation updateProducto($Id: ID!, $data: ProductoInput) {\n  updateProducto(Id: $Id, data: $data)\n}"}'
```

{% endtab %}

{% tab title="C#" %}

```csharp
var client = new RestClient("https://MY_APPLICATION_DOMAIN/graphql");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer TOKEN_RECEIVED_ABOVE_xxxxxxx");
request.AddHeader("content-type", "application/json");
request.AddHeader("x-userid", "4"); //pass this is if you need an user in the server logic
var body = @"{""operationName"":""updateProducto"",""variables"":{""Id"":""24"",""data"":{""CalcularImpuestos"":false,""CategoriaId"":""2"",""Codigo"":""B- Frutal Mango 500ML"",""Costo"":2000,""DescuentoEmpleadoAplicable"":false,""Facturable"":true,""MostrarEnInventario"":true,""Id"":""24"",""Nombre"":""FRUTAL MANGO 500ML"",""PosClientId"":""0d3ZGanGSO6NxXgx"",""Precio"":3000,""SincronizacionFacturaId"":""927"",""Sincronizado"":true,""SumarImpuestosAlPrecio"":false,""GastoFijo"":false,""Combos__ProductoPadreId"":[]}},""query"":""mutation updateProducto($Id: ID!, $data: ProductoInput) {\n  updateProducto(Id: $Id, data: $data)\n}""}";
request.AddParameter("application/json", body,  ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
```

{% endtab %}
{% endtabs %}

### Consuming from a browser

If you are planning to consume any endpoint from a browser (Client-side) you will need to configure the CORS and allow from which domain you are consuming the API

To allow a domain to consume any Codenull API endpint you must add it on Application Settings section


---

# Agent Instructions: 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:

```
GET https://codenull.gitbook.io/dev/configurations/integrations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
