Introduzione

API Endpoint

https://api.balin.app/external_api/v1/

Balin.app mette a disposizione un servizio REST API, per integrazioni nelle vostre applicazioni.

Questa documentazione fornisce informazioni sugli endpoint disponibili e su come interagire con essi.

Endpoint REST API: https://api.balin.app/external_api/v1/

Attivazione API

Per attivare il servizo di REST API di Balin.app bisogna andare sulle impostazioni del proprio profilo utente in balin.app.
Dove sarà possibile abilitare/disabilitare il servizio REST API e ottenere api_token da usare per l'autenticazione.

Abilitazione sotto utenti

Per i sotto utenti sarà necessario che il proprietario principale dell'account conceda i permessi di visualizzazione sui veicoli interessati e che nella sezione di creazione/modifica del sotto utente abiliti le seguenti funzionalità:

  • Utilizzo dello storico percorsi → per ottenre lo storico posizioni di un localizzatore GPS.
  • Utilizzo del report → per ottenre lo storico del viaggio ovvero le tappe effettuate da un localizzatore GPS.

Autenticazione

Example header Basic Auth

--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);

xhr.setRequestHeader("Authorization", "Basic " + hash);
        
var request = require('request');
var token = <email> + ":" + <api_token>>
var hash = btoa(token);
var options = {
  'method': 'GET',
  'url': 'https://api.balin.app/external_api/v1/<api_path>',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
        
import http.client
import base64

conn = http.client.HTTPSConnection("api.balin.app")
hash = base64.b64encode(b'<email>:<api_token>>')
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("GET", "/external_api/v1/<api_path>", payload, headers)
        

Dopo aver attivato il servizio API dal portale, si potrà utilizzare l'api_token in associazione all'email dell'account per autenticare le richieste HTTP.

Questi parametri andranno inseriti all'interno dell'header delle richieste HTTP come Basic Athentication:

  • Username - your email
  • Password - api_token

Se l'autenticazione fallisce, sarà restituito un JSON object di tipo Error e con HTTP status 401.

Versioning

Tutte le chiamate API dovrebbero includere nel path la versione con cui desideri effettuare la richiesta. La versione attuale è la v1.

Se non viene passata alcuna versione, verrà utilizzata l'ultima versione dell'API. Assicurati di includere una versione valida in ogni richiesta per evitare problemi nell'integrazione con il tuo sistema.

Example path: https://api.balin.app/external_api/v1/<requested_path>

Paginazione

Example request

curl --location --request GET 'https://api.balin.app/external_api/v1/<api_path>&skip=0&limit=1500' \
--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("GET", "https://api.balin.app/external_api/v1/<api_path>&skip=0&limit=1500");
xhr.setRequestHeader("Authorization", "Basic " + hash);
xhr.send();
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'GET',
  'url': 'https://api.balin.app/external_api/v1/<api_path>&skip=0&limit=1500',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

conn = http.client.HTTPSConnection("api.balin.app")
hash = base64.b64encode(b'<email>:<api_token>>')
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("GET", "/external_api/v1/<api_path>&skip=0&limit=1500", payload, headers)
res = conn.getresponse()
data = res.read()
        

Tutti gli endpoint GET che restituiscono un elenco di oggetti supportano la paginazione.
Ciò significa che per ottenere tutti gli oggetti, è necessario impaginare i risultati utilizzando sempre gli stessi parametri con il valore di skip che indica quanti elementi saltare nell'elenco.
Tutti i risultati sono reperiti quando has_more della risposta è false. Il numero di elementi massimo in lista è specificato tramite limit ed è impostato su 1500 ma sono consentiti valori fino a 15000.

Parametri

Parameter Description
limit optional Numero di elementi per chiamata. Valori accettati: 1500 - 15000. Default 1500
skip optional Numero di elementi da saltare ricevuti da chiamata precedente. Default 0

Example response

{
    "limit": 1500,
    "skip": 0,
    "data": [...] /** 1500 elements **/,
    "has_more": true
}
        

Risposta

Parameter Description
limit numeric, integer Numero di elementi richiesti nella chiamata
skip numeric, integer Numero di elementi saltati come richiesti in chiamata
has_more boolean true se ci sono ancora elementi nella lista richiesta ed è quindi necessaria una chiamata successiva di paginazione.
data array Lista di oggetti nella pagina.

Limiti utilizzo

Le nostre API sono gratuite ma hanno un limite di utilizzo di non più una richiesta al secondo.

Errori

Error response with HTTP error code

{
    "type": 1,
    "description": "Descrizione dello specifico errore"
}
        

Tutti gli errori includono un oggetto JSON con campo type che ne identifica il tipo e una descrizione dell'errore in description.

Per ogni chiamata descritta in questa documentazione vengono forniti i codici dei relativi errori ad esclusione di quelli comuni a tutte le chiamate API, che sono:

Errori comuni

Example error with code 401

{
    "type": 3,
    "description": "The user is not enabled for external APIs"
}
        
Error code type Spiegazione
401 1 Autenticazione errata, email o api_token invalidi
401 2 Nessun utente trovato in balin.app con l'email specificata
401 3 Servizio REST API non abilitato per questo utente
401 4 Non autorizzato per mancanza di pagamenti in sospeso
429 5 Hai superato il limite massimo di richieste API, attenti e riprova
500 1 Errore interno del server

Device

Oggetto che descrive il dispositivo di localizzazione GPS.

Device resource

{
    "imei": "359633109558000",
    "serial": "1107710000",
    "name": "Vehicle 1",
    "numeric_label": 1,
    "timestamp_activation": 1608546968000,
    "lng": 7.8481616,
    "lat": 44.6996966,
    "heading": 116,
    "odometer": 5657910,
    "altitude": 255,
    "speed": 15,
    "satellites": 14,
    "moving": false,
    "timestamp_position": 1626097725000,
    "timestamp_last_trip_change": 1626071092000,
    "has_GPS": true,
    "is_connected": false,
    "is_power_on": false
}
        
Field Type Description
imei string Codice IMEI del localizzatore GPS
serial string Codice seriale del localizzatore GPS
name string Nome testuale assegnato dal proprietario sulla nostra piattaforma
numeric_label string Etichetta numerica assegnata dal proprietario sulla nostra piattaforma
timestamp_activation timestamp in ms Quando è stato attivato il localizzatore GPS
lng numeric, decimal Longitudine dell'ultima posizione inviata
lat numeric, decimal Latitudine dell'ultima posizione inviata
heading numeric, integer Direzione del dispositivo nell'ultima posizione inviata (0 - 359)
speed numeric, decimal in Km/h Velocità del veicolo nell'ultima posizione inviata
odometer numeric, integer in metri Odometro totale del dispositivo nell'ultima posizione registrata
altitude numeric, integer in metri Altitudine nell'ultima posizione registrata
satellites numeric, integer Numero di satelliti a cui è collegato il localizzatore. Più satelli sono collegati migliore sarà la precisione della posizione rilevata
moving boolean true se il localizzatore è in viaggio
false se il localizzatore è fermo
timestamp_last_trip_change timestamp in ms Timestamp in ms dell'ultimo cambio di stato del parametro moving.
Se moving == true allora timestamp_last_trip_change indica il timestamp in ms da quando il localizzatore è in viaggio
Se moving == false allora timestamp_last_trip_change indica il timestamp in ms da quando il localizzatore è fermo
timestamp_position timestamp in ms Quando è stata ricevuta l'ultima posizione GPS
has_GPS boolean Se true significa che il localizzatore è correttamente collegato alla rete GPS
is_connected boolean Se true significa che il localizzatore è correttamente collegato alla rete internet per la trasmissione dei dati
is_power_on boolean Se true significa che il localizzatore è correttamente alimentato

Ottenere i device

Example request

curl --location --request GET 'https://api.balin.app/external_api/v1/devices' \
--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("GET", "https://api.balin.app/external_api/v1/devices");
xhr.setRequestHeader("Authorization", "Basic " + hash);

xhr.send();
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'GET',
  'url': 'https://api.balin.app/external_api/v1/devices',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

hash = base64.b64encode(b'<email>:<api_token>>')
conn = http.client.HTTPSConnection("api.balin.app")
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("GET", "/external_api/v1/devices", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
        

Tramite questa API è possibile ottenere l'elenco dei localizzatori GPS disponibili come lista di oggetti JSON di tipo Device.
La lista di localizzatori disponibili varia a seconda del tipo di utente che effettua la chiamata:

  • Utente proprietario - L'utente proprietario dell'account vedrà tutti i localizzatori in suo possesso e che risultano attivi.
  • Sotto utente - Un sotto-utente vedra solo i localizzatori a cui è stata autorizzata la visualizzazione da parte dell'utente proprietario.

HTTP Request

Questa richiesta necessita di autenticazione e non necessita di paginazione ovvero viene ritornata tutta la lista disponibile.

GET https://api.balin.app/external_api/v1/devices

HTTS Response

Example response

[
  {
    "imei": "359633109558000",
    "serial": "1107710000",
    "name": "Vehicle 1",
    "numeric_label": 2,
    "timestamp_activation": 1606299832000,
    "lng": 7.8483633,
    "lat": 44.69949,
    "heading": 235,
    "odometer": 87,
    "altitude": 272,
    "speed": 22,
    "satellites": 11,
    "moving": true,
    "timestamp_position": 1610612540000,
    "timestamp_last_trip_change": 1607080145000,
    "has_GPS": false,
    "is_connected": false,
    "is_power_on": false
  },
  {
    "imei": "359633109558001",
    "serial": "1107710001",
    "name": "Vehicle 2",
    "numeric_label": 2,
    "timestamp_activation": 1608546968000,
    "lng": 7.8481616,
    "lat": 44.6996966,
    "heading": 116,
    "odometer": 5657910,
    "altitude": 255,
    "speed": 0,
    "satellites": 14,
    "moving": false,
    "timestamp_position": 1626097725000,
    "timestamp_last_trip_change": 1626071092000,
    "has_GPS": true,
    "is_connected": false,
    "is_power_on": false
  }
]
        

Una lista di Device.

HTTP Errors

Oggetto di tipo Error:

Error code type Spiegazione
401 1 Autenticazione errata, email o api_token invalidi
401 2 Nessun utente trovato in balin.app con l'email specificata
401 3 Servizio REST API non abilitato per questo utente
401 4 L'utente non appartiene a balin.app
401 5 Non autorizzato per mancanza di pagamenti in sospeso
500 1 Errore interno del server

Ottenere un device

Example request

curl --location --request GET 'https://api.balin.app/external_api/v1/device/359633109558000' \
--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("GET", "https://api.balin.app/external_api/v1/device/359633109558000");
xhr.setRequestHeader("Authorization", "Basic " + hash);

xhr.send();
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'GET',
  'url': 'https://api.balin.app/external_api/v1/device/359633109558000',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

hash = base64.b64encode(b'<email>:<api_token>>')
conn = http.client.HTTPSConnection("api.balin.app")
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("GET", "/external_api/v1/device/359633109558000", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
        

Ritorna un singolo device specifico, identificato dall'imei.

HTTP Request

Questa richiesta necessita di autenticazione.

GET https://api.balin.app/external_api/v1/device/:imei

Parametri

Parameter Location Description
imei string, required params Codice imei del localizzatore GPS

HTTS Response

Example response

{
  "imei": "359633109558000",
  "serial": "1107710000",
  "name": "Vehicle 1",
  "numeric_label": 2,
  "timestamp_activation": 1606299832000,
  "lng": 7.8483633,
  "lat": 44.69949,
  "heading": 235,
  "odometer": 87,
  "altitude": 272,
  "speed": 22,
  "satellites": 11,
  "moving": true,
  "timestamp_position": 1610612540000,
  "timestamp_last_trip_change": 1607080145000,
  "has_GPS": false,
  "is_connected": false,
  "is_power_on": false
}
        

Un oggetto JSON di tipo Device.

HTTP Errors

Oggetto di tipo Error:

Error code type Spiegazione
400 1 Errore nei parametri della chiamata
400 2 Nessun localizzatore trovato con questo imei
400 3 L'utente non dispone dei permessi di visualizzazione del localizzatore.

Position

Oggetto che descrive la posizione GPS. Si differenzia da Device perchè descrive una posizione generica registrata dal dispositivo e quindi utile per le richieste di storico e per la lettura delle varie tipologie di eventi inviati dal localizzatore GPS.

Position resource

{
  "lng": 14.771271,
  "lat": 40.925031,
  "heading": 28,
  "altitude": 0,
  "speed": 27,
  "timestamp": 1637768035000,
  "type": 1
}
        
Field Type Description
lng numeric, decimal Longitudine della posizione
lat numeric, decimal Latitudine della posizione
heading numeric, integer Direzione del dispositivo in questa posizione (0 - 359)
altitude numeric, integer in metri Altitudine della posizione
speed numeric, decimal in Km/h Velocità del veicolo in questa posizione
timestamp_position timestamp in ms Quando è stata registrata questa posizione
type numeric, integer Tipologia della posizione:
1 → Posizione GPS semplice, ovvero coordinate geografiche senza specifici eventi avvenuti sul localizzatore;
2 → E' avvenuto un evento di collegamento alimentazione del localizzatore GPS
3 → E' avvenuto un evento di scollegamento alimentazione del localizzatore GPS
4 → E' avvenuto un evento di inizio di viaggio del localizzatore GPS
5 → E' avvenuto un evento di sosta del localizzatore GPS
6 → E' avvenuto un evento movimento del localizzatore GPS in seguito ad una ripartenza o anche solo per il movimento fisico del dispositivo
7 → E' avvenuto un evento fermo del localizzatore GPS in seguito ad una sosta o anche solo per il dispositivo non si muove fisicamente da un po' di tempo
8 → E' avvenuto un evento di on sull'input 1 del localizzatore GPS (solo per il modello FMB920)
9 → E' avvenuto un evento di off sull'input 1 del localizzatore GPS (solo per il modello FMB920)
10 → E' avvenuto un evento di on sull'output 1 del localizzatore GPS (solo per il modello FMB920)
11 → E' avvenuto un evento di off sull'output 1 del localizzatore GPS (solo per il modello FMB920)
odometer numeric, integer in metri Presente solo se type == 5 , sono i metri percorsi durante l'ultimo trip

Storico posizioni

Example request

curl --location --request GET 'https://api.balin.app/external_api/v1/positionsHistory/359633109558000?start=1637756247000&stop=1637842647000&skip=0&limit=1500&filter_type=1&filter_type=2' \
--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("GET", "https://api.balin.app/external_api/v1/positionsHistory/359633109558000?start=1637756247000&stop=1637842647000&skip=0&limit=1500&filter_type=1&filter_type=2");
xhr.setRequestHeader("Authorization", "Basic " + hash);

xhr.send();
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'GET',
  'url': 'https://api.balin.app/external_api/v1/positionsHistory/359633109558000?start=1637756247000&stop=1637842647000&skip=0&limit=1500&filter_type=1&filter_type=2',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

hash = base64.b64encode(b'<email>:<api_token>>')
conn = http.client.HTTPSConnection("api.balin.app")
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("GET", "/external_api/v1/positionsHistory/359633109558000?start=1637756247000&stop=1637842647000&skip=0&limit=1500&filter_type=1&filter_type=2", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
        

Ritorna un oggetto di tipo Paginazione con una lista di Position, registrate dal dispositivo, in un determinato intervallo temporale ed eventualmente filtrate per tipologia (campo type di Position).

Request LIMITS

La richiesta di storico posizioni deve rispettare i seguenti limiti:

  • Non si possono richiedere posizioni più vecchie di 30 giorni → Il parametro start non deve essere un timestamp entro 30 giorni dal momento della richiesta.
  • Il range temporale deve essere al massimo di 1 giorno → La differenza tra i parametri start e stop non deve essere più grande di 1 giorno.

HTTP Request

Questa richiesta necessita di autenticazione.

GET https://api.balin.app/external_api/v1/positionsHistory/:imei

Parametri

Parameter Location Description
imei string, required params Codice imei del localizzatore GPS
start timestamp in ms, required query url Timestamp inizio intervallo richiesta storico
stop timestamp in ms, required query url Timestamp fine intervallo richiesta storico
filter_type array di integer, optional query url Lista di type di Position da filtrare, se non specificato non viene applicato alcun filtro sulla tipologia di posizioni
limit numeric, integer, optional query url Dettagli in Paginazione
skip numeric, integer, optional query url Dettagli in Paginazione

HTTS Response

Example response

{
  "limit": 1500,
  "skip": 0,
  "data": [
    {
      "lng": 14.771271,
      "lat": 40.925031,
      "heading": 28,
      "altitude": 0,
      "speed": 27,
      "timestamp": 1637768035000,
      "type": 1
    },
    {
      "lng": 14.771307,
      "lat": 40.925097,
      "heading": 23,
      "altitude": 0,
      "speed": 27,
      "timestamp": 1637768036000,
      "type": 1
    },
    {
      "lng": 14.771539,
      "lat": 40.925631,
      "heading": 34,
      "altitude": 0,
      "speed": 26,
      "timestamp": 1637768044000,
      "type": 2
    },
    {
      "lng": 14.771426,
      "lat": 40.926715,
      "heading": 332,
      "altitude": 0,
      "speed": 41,
      "timestamp": 1637768064000,
      "type": 1
    }
  ],
  "has_more": true
}
        

Un oggetto JSON di come inficato paginazione con all'interno una lista di oggetti Position.

HTTP Errors

Oggetto di tipo Error:

Error code type Spiegazione
400 1 Errore nei parametri della richiesta
400 2 La richiesta non rispetta i limiti temporali di storico delle posizioni del localizzatore
400 3 Nessun localizzatore trovato con questo imei
400 4 L'utente non dispone dei permessi di visualizzazione del localizzatore.
401 20 Solo per sotto-utenti. Il sotto utente non ha i permessi per la visualizzazione dello storico. Deve essere richiesta al proprietario.

Storico viaggio

Example request

curl --location --request GET 'https://api.balin.app/external_api/v1/tripPositionsHistory/359633109558000?start=1637756247000&stop=1637842647000&skip=0&limit=1500' \
--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("GET", "https://api.balin.app/external_api/v1/tripPositionsHistory/359633109558000?start=1637756247000&stop=1637842647000&skip=0&limit=1500");
xhr.setRequestHeader("Authorization", "Basic " + hash);

xhr.send();
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'GET',
  'url': 'https://api.balin.app/external_api/v1/tripPositionsHistory/359633109558000?start=1637756247000&stop=1637842647000&skip=0&limit=1500',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

hash = base64.b64encode(b'<email>:<api_token>>')
conn = http.client.HTTPSConnection("api.balin.app")
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("GET", "/external_api/v1/tripPositionsHistory/359633109558000?start=1637756247000&stop=1637842647000&skip=0&limit=1500", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
        

Ritorna un oggetto di tipo Paginazione con una lista di Position esclusivamente con type == 4 e type == 5 registrate dal dispositivo in un determinato intervallo temporale.
Ovvero otterremo una lista di posizioni che descrivono i vari e successivi eventi di cambio stato viaggio/sosta del dispositivo (veicolo). In questo modo è quindi possibile avere tutte le tappe di un itinerario.

Request LIMITS

La richiesta di storico viaggio deve rispettare i seguenti limiti:

  • Non si possono richiedere posizioni più vecchie di 90 giorni → Il parametro start non deve essere un timestamp entro 90 giorni dal momento della richiesta.
  • Il range temporale deve essere al massimo di 90 giorni → La differenza tra i parametri start e stop non deve essere più grande di 90 giorni.

HTTP Request

Questa richiesta necessita di autenticazione.

GET https://api.balin.app/external_api/v1/tripPositionsHistory/:imei

Parametri

Parameter Location Description
imei string, required params Codice imei del localizzatore GPS
start timestamp in ms, required query url Timestamp inizio intervallo richiesta storico
stop timestamp in ms, required query url Timestamp fine intervallo richiesta storico
limit numeric, integer, optional query url Dettagli in Paginazione
skip numeric, integer, optional query url Dettagli in Paginazione

HTTS Response

Example response

{
  "limit": 1500,
  "skip": 0,
  "data": [
    {
      "lng": 14.77175,
      "lat": 40.925917,
      "heading": 9,
      "altitude": 0,
      "speed": 29,
      "timestamp": 1637768049000,
      "type": 4,
    },
    {
      "lng": 14.771213,
      "lat": 40.92701,
      "heading": 330,
      "altitude": 0,
      "speed": 44,
      "timestamp": 1637768067000,
      "type": 5,
      "odometer": 29084
    },
    {
      "lng": 14.763393,
      "lat": 40.92607,
      "heading": 144,
      "altitude": 0,
      "speed": 34,
      "timestamp": 1637768131000,
      "type": 4,
    },
    {
      "lng": 14.766297,
      "lat": 40.919562,
      "heading": 160,
      "altitude": 0,
      "speed": 34,
      "timestamp": 1637768212000,
      "type": 4,
      "odometer": 23085
    }
  ],
  "has_more": true
}
        

Un oggetto JSON di come inficato paginazione con all'interno una lista di oggetti Position.

HTTP Errors

Oggetto di tipo Error:

Error code type Spiegazione
400 1 Errore nei parametri della richiesta
400 2 La richiesta non rispetta i limiti temporali di storico delle posizioni del localizzatore
400 3 Nessun localizzatore trovato con questo imei
400 4 L'utente non dispone dei permessi di visualizzazione del localizzatore.
401 20 Solo per sotto-utenti. Il sotto utente non ha i permessi per la visualizzazione del report. Deve essere richiesta al proprietario.

Link condivisione

Oggetto che descrive un link condivisione, ovvero un link che si può condividere al di fuori del sistema che permette ad utenti esterni di visualizzare temporaneamente la posizione di un veicolo.

{
  "_id": "68d4f2d476cb0109405f0001",
  "target_imei": 357073294000001,
  "name": "Link per cliente esterno",
  "note": "L'utente info@balin.com ha condiviso con te la posizione di Land Rover",
  "expiration_date": 1760686980000,
  "emails": ["cliente@balin.app", "cliente2@balin.app"],
  "token": "9KX3xNzT001"
  "url": "https://web.balin.app/share-posizione?c=9KX3xNzT001",
  "created": "1758723966441"
}
        
Field Type Description
_id string Identificativo dell'oggetto, serve per l'eliminazione del link
target_imei numeric, integer Codice IMEI del dispositivo di cui si vuole condividere la posizione del link
name string Nome testuale del link che serve esclusivamente per identificarlo in maniera semplice
note string Testo che verrà visualizzato dal destinatario del link. Consigliamo quindi di mettere solo le informazioni necessarie.
expiration_date numeric, timestamp in ms Data di scadenza del link. Dopo tale data il link non sarà più utilizzabile.
emails string[], array di string Lista di email a cui sono state inviate automaticamente le mail con il link.
token string Token identificativo del link, che è inglobato nel campo url.
url string Url che può essere condivisso all'esterno e che permette la visualizzazione della posizione condivisa in questo link.
created numeric, timestamp in ms Data creazione del link.

Example request

curl --location --request POST 'https://api.balin.app/external_api/v1/link_condivisione' \
--header 'Authorization: Basic <your_btoa_token>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "target_imei": 357073294000001,
  "name": "Link per cliente esterno",
  "note": "L'utente info@balin.com ha condiviso con te la posizione di Land Rover",
  "expiration_date": 1760686980000,
  "emails": ["cliente@balin.app", "cliente2@balin.app"],
}'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("POST", "https://api.balin.app/external_api/v1/link_condivisione");
xhr.setRequestHeader("Authorization", "Basic " + hash);
xhr.setRequestHeader("Content-Type", "application/json");

var body = {
  target_imei: 357073294000001,
  name: "Link per cliente esterno",
  note: "L'utente info@balin.com ha condiviso con te la posizione di Land Rover",
  expiration_date: 1760686980000,
  emails: ["cliente@balin.app", "cliente2@balin.app"]
};

xhr.send(JSON.stringify(body));
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'POST',
  'url': 'https://api.balin.app/external_api/v1/link_condivisione',
  'headers': {
    'Authorization': 'Basic ' + hash,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    target_imei: 357073294000001,
    name: "Link per cliente esterno",
    note: "L'utente info@balin.com ha condiviso con te la posizione di Land Rover",
    expiration_date: 1760686980000,
    emails: ["cliente@balin.app", "cliente2@balin.app"]
  })
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

hash = base64.b64encode(b'<email>:<api_token>>')
conn = http.client.HTTPSConnection("api.balin.app")
payload = {
    "target_imei": 357073294000001,
    "name": "Link per cliente esterno",
    "note": "L'utente info@balin.com ha condiviso con te la posizione di Land Rover",
    "expiration_date": 1760686980000,
    "emails": ["cliente@balin.app", "cliente2@balin.app"]
}
headers = {
  'Authorization': 'Basic ' + hash,
  "Content-Type": "application/json"
}
conn.request("POST", "/external_api/v1/link_condivisione", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
        

Tramite questa API è possibile creare un link di condivisione di posizione di un tuo veicolo.

HTTP Request

Questa richiesta necessita di autenticazione.

POST https://api.balin.app/external_api/v1/link_condivisione

Parametri

Parameter Location Description
target_imei string, required body Nome testuale del link che serve esclusivamente per identificarlo in maniera semplice.
expiration_date numeric, timestamp ms, optional body Timestamp in ms della date in cui si vuole far scadere il link.
name string, optional body IMEI dei dispositivo di cui si vuole condividere la posizione nel link.
note string, optional body Testo che verrà visualizzato dal destinatario del link. Consigliamo quindi di mettere solo le informazioni necessarie.
emails string[], optional body Lista di email a cui sono state inviate automaticamente le mail con il link.

HTTS Response

Example response

{
  "_id": "68d4f2d476cb0109405f0001",
  "target_imei": 357073294000001,
  "name": "Link per cliente esterno",
  "note": "L'utente info@balin.com ha condiviso con te la posizione di Land Rover",
  "expiration_date": 1760686980000,
  "emails": ["cliente@balin.app", "cliente2@balin.app"],
  "token": "9KX3xNzT001"
  "url": "https://web.balin.app/share-posizione?c=9KX3xNzT001",
  "created": "1758723966441"
}
        

Il link appena creato in un oggetto di tipo Link Condivisione.

HTTP Errors

Oggetto di tipo Error:

Error code type Spiegazione
401 1 Autenticazione errata, email o api_token invalidi.
401 2 Problemi con i parametri nel body della richiesta POST.
401 3 Problemi con la data di scadenza del link.
401 4 Problemi con il device di cui si vuole condividere la posizione.
500 1 Errore interno del server

Example request

curl --location --request GET 'https://api.balin.app/external_api/v1/link_condivisione?skip=0&limit=100' \
--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("GET", "https://api.balin.app/external_api/v1/link_condivisione?skip=0&limit=100");
xhr.setRequestHeader("Authorization", "Basic " + hash);

xhr.send();
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'GET',
  'url': 'https://api.balin.app/external_api/v1/link_condivisione?skip=0&limit=100',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

hash = base64.b64encode(b'<email>:<api_token>>')
conn = http.client.HTTPSConnection("api.balin.app")
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("GET", "/external_api/v1/link_condivisione?skip=0&limit=100", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
        

Tramite questa API è possibile ottenere l'elenco dei link di condivisioni che sono stati creati sul tuo account come lista di oggetti JSON di tipo Link Condivisione.

HTTP Request

Questa richiesta necessita di autenticazione e paginazione.

GET https://api.balin.app/external_api/v1/link_condivisione

Parametri

Parameter Location Description
limit numeric, integer, optional query url Dettagli in Paginazione
skip numeric, integer, optional query url Dettagli in Paginazione

HTTS Response

Example response

[
  {
    "_id": "68d4f2d476cb0109405f0001",
    "target_imei": 357073294000001,
    "name": "Link per cliente esterno",
    "note": "L'utente info@balin.com ha condiviso con te la posizione di Land Rover",
    "expiration_date": 1760686980000,
    "emails": ["cliente@balin.app", "cliente2@balin.app"],
    "token": "9KX3xNzT001"
    "url": "https://web.balin.app/share-posizione?c=9KX3xNzT001",
    "created": "1758723966441"
  },
  {
    "_id": "68d4f2d476cb0109405f0002",
    "target_imei": 357073294000002,
    "name": "Link per cliente esterno 2",
    "note": "L'utente info@balin.com ha condiviso con te la posizione di BMW",
    "expiration_date": 1760686985000,
    "emails": ["cliente@balin.app", "cliente2@balin.app"],
    "token": "9KX3xNzT002"
    "url": "https://web.balin.app/share-posizione?c=9KX3xNzT002",
    "created": "1758723976441"
  }
]
        

Una lista di Link Condivisione.

HTTP Errors

Oggetto di tipo Error:

Error code type Spiegazione
401 1 Autenticazione errata, email o api_token invalidi
500 1 Errore interno del server

Example request

curl --location --request GET 'https://api.balin.app/external_api/v1/link_condivisione/68d4f2d476cb0109405f0001' \
--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("GET", "https://api.balin.app/external_api/v1/link_condivisione/68d4f2d476cb0109405f0001");
xhr.setRequestHeader("Authorization", "Basic " + hash);

xhr.send();
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'GET',
  'url': 'https://api.balin.app/external_api/v1/link_condivisione/68d4f2d476cb0109405f0001',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

hash = base64.b64encode(b'<email>:<api_token>>')
conn = http.client.HTTPSConnection("api.balin.app")
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("GET", "/external_api/v1/link_condivisione/68d4f2d476cb0109405f0001", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
        

Tramite questa API è possibile ottenere un link di condivisione partendo dal suo _id.

HTTP Request

Questa richiesta necessita di autenticazione.

GET https://api.balin.app/external_api/v1/link_condivisione/:_id

Parametri

Parameter Location Description
_id string, required params _id del link che si vuole ottenere (vedi Link Condivisione).

HTTS Response

Example response

{
  "_id": "68d4f2d476cb0109405f0001",
  "target_imei": 357073294000001,
  "name": "Link per cliente esterno",
  "note": "L'utente info@balin.com ha condiviso con te la posizione di Land Rover",
  "expiration_date": 1760686980000,
  "emails": ["cliente@balin.app", "cliente2@balin.app"],
  "token": "9KX3xNzT001"
  "url": "https://web.balin.app/share-posizione?c=9KX3xNzT001",
  "created": "1758723966441"
}
        

L'oggetto di tipo Link Condivisione del link richiesto.

HTTP Errors

Oggetto di tipo Error:

Error code type Spiegazione
401 1 Autenticazione errata, email o api_token invalidi
401 2 Problemi con il parametro della richiesta GET.
401 3 Problemi con il device di cui si vuole condividere la posizione.
500 1 Errore interno del server

Example request

curl --location --request DELETE 'https://api.balin.app/external_api/v1/link_condivisione/68d4f2d476cb0109405f0001' \
--header 'Authorization: Basic <your_btoa_token>'
        
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
  if(this.readyState === 4) {
    console.log(this.responseText);
  }
});
var token = <email> + ":" + <api_token>
var hash = btoa(token);
xhr.open("DELETE", "https://api.balin.app/external_api/v1/link_condivisione/68d4f2d476cb0109405f0001");
xhr.setRequestHeader("Authorization", "Basic " + hash);

xhr.send();
        
var request = require('request');
var token = <email> + ":" + <api_token>
var hash = btoa(token);
var options = {
  'method': 'DELETE',
  'url': 'https://api.balin.app/external_api/v1/link_condivisione/68d4f2d476cb0109405f0001',
  'headers': {
    'Authorization': 'Basic ' + hash
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
        
import http.client
import base64

hash = base64.b64encode(b'<email>:<api_token>>')
conn = http.client.HTTPSConnection("api.balin.app")
payload = ''
headers = {
  'Authorization': 'Basic ' + hash
}
conn.request("DELETE", "/external_api/v1/link_condivisione/68d4f2d476cb0109405f0001", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
        

Tramite questa API è possibile eliminare un link dato il suo _id. L'operazione non è reversibile.

HTTP Request

Questa richiesta necessita di autenticazione.

DELETE https://api.balin.app/external_api/v1/link_condivisione/:_id

Parametri

Parameter Location Description
_id string, required params _id del link che si vuole eliminare (vedi Link Condivisione).

HTTS Response

Example response

{result: 'Cancellato'}
        

Un oggetto indicante la conferma di cancellazione.

HTTP Errors

Oggetto di tipo Error:

Error code type Spiegazione
401 1 Autenticazione errata, email o api_token invalidi
401 2 Problemi con il parametro della richiesta GET.
401 3 Problemi con il device di cui si vuole condividere la posizione.
500 1 Errore interno del server