Autenticazione OAuth 2.0
UniMsg utilizza OAuth 2.0 con il flusso Client Credentials per l'autenticazione API. Questo flusso è ideale per comunicazioni server-to-server dove non è richiesta l'interazione utente.
Credenziali
Per autenticarti, hai bisogno di:
| Credenziale | Descrizione | Esempio |
|---|---|---|
client_id |
Identificativo pubblico del client | demo_xxxxxxxxxxxx |
client_secret |
Chiave segreta (mai condividere!) | sk_test_xxxxxxxxxxxx |
Trovi le credenziali in: Dashboard → Impostazioni → API
Sicurezza: Non includere mai
client_secret nel codice client-side (browser, app mobile). Usa sempre chiamate server-side.
Ottenere un Access Token
POST
/oauth/token
Richiesta
POST /oauth/token HTTP/1.1
Host: api.unimsg.app
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=demo_xxxxxxxxxxxx&client_secret=sk_test_xxxxxxxxxxxx
Parametri
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
grant_type |
string | Sì | Deve essere client_credentials |
client_id |
string | Sì | Il tuo Client ID |
client_secret |
string | Sì | Il tuo Client Secret |
scope |
string | No | Scopes separati da spazio |
Risposta Successo
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FwaS51bmltc2cuYXBwIiwic3ViIjoiY2xpZW50XzEyMzQ1Iiwic2NvcGVzIjpbInNtczpzZW5kIiwiZW1haWw6c2VuZCJdLCJleHAiOjE3MDUzMjU2MDB9.signature",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "sms:send email:send whatsapp:send telegram:send"
}
Risposta Errore
{
"error": "invalid_client",
"error_description": "Client authentication failed"
}
Usare l'Access Token
Includi l'access token nell'header Authorization di ogni richiesta API:
GET /v1/account/balance HTTP/1.1
Host: api.unimsg.app
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Scopes Disponibili
Gli scopes limitano le operazioni che un token può eseguire:
| Scope | Descrizione |
|---|---|
sms:send |
Invio SMS |
sms:read |
Lettura stato SMS |
whatsapp:send |
Invio WhatsApp |
whatsapp:read |
Lettura stato WhatsApp |
email:send |
Invio Email |
email:read |
Lettura stato Email |
telegram:send |
Invio Telegram |
telegram:read |
Lettura stato Telegram |
account:read |
Lettura info account e crediti |
Se non specifichi scope, il token avrà tutti gli scope disponibili per il tuo account.
Durata Token
Gli access token hanno una durata di 1 ora (3600 secondi). Quando scade:
- Le richieste API restituiranno errore
401 Unauthorized - Richiedi un nuovo token con le stesse credenziali
- Non è necessario "invalidare" il vecchio token
Best Practice: Salva il token e
expires_in. Rinnova il token qualche minuto prima della scadenza per evitare interruzioni.
Esempi di Codice
cURL
curl -X POST https://api.unimsg.app/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=demo_xxxxxxxxxxxx" \
-d "client_secret=sk_test_xxxxxxxxxxxx"
PHP
<?php
class UniMsgClient
{
private string $clientId;
private string $clientSecret;
private ?string $accessToken = null;
private ?int $tokenExpiry = null;
public function __construct(string $clientId, string $clientSecret)
{
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
}
public function getAccessToken(): string
{
// Check if token is still valid
if ($this->accessToken && $this->tokenExpiry > time() + 60) {
return $this->accessToken;
}
// Request new token
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.unimsg.app/oauth/token',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'client_credentials',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret
])
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
if (isset($data['access_token'])) {
$this->accessToken = $data['access_token'];
$this->tokenExpiry = time() + $data['expires_in'];
return $this->accessToken;
}
throw new Exception('Failed to obtain access token');
}
}
Python
import requests
import time
class UniMsgClient:
def __init__(self, client_id: str, client_secret: str):
self.client_id = client_id
self.client_secret = client_secret
self.access_token = None
self.token_expiry = 0
def get_access_token(self) -> str:
# Check if token is still valid
if self.access_token and self.token_expiry > time.time() + 60:
return self.access_token
# Request new token
response = requests.post(
'https://api.unimsg.app/oauth/token',
data={
'grant_type': 'client_credentials',
'client_id': self.client_id,
'client_secret': self.client_secret
}
)
data = response.json()
if 'access_token' in data:
self.access_token = data['access_token']
self.token_expiry = time.time() + data['expires_in']
return self.access_token
raise Exception('Failed to obtain access token')
Node.js
const axios = require('axios');
class UniMsgClient {
constructor(clientId, clientSecret) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.accessToken = null;
this.tokenExpiry = 0;
}
async getAccessToken() {
// Check if token is still valid
if (this.accessToken && this.tokenExpiry > Date.now() + 60000) {
return this.accessToken;
}
// Request new token
const response = await axios.post(
'https://api.unimsg.app/oauth/token',
new URLSearchParams({
grant_type: 'client_credentials',
client_id: this.clientId,
client_secret: this.clientSecret
})
);
if (response.data.access_token) {
this.accessToken = response.data.access_token;
this.tokenExpiry = Date.now() + (response.data.expires_in * 1000);
return this.accessToken;
}
throw new Error('Failed to obtain access token');
}
}
Errori di Autenticazione
| Codice HTTP | Error | Descrizione |
|---|---|---|
| 400 | invalid_request |
Parametri mancanti o non validi |
| 401 | invalid_client |
Credenziali non valide |
| 401 | invalid_token |
Token scaduto o revocato |
| 403 | insufficient_scope |
Token non ha lo scope richiesto |
Security Best Practices
- Non condividere il Client Secret - Trattalo come una password
- Usa HTTPS - Mai inviare credenziali su HTTP
- Server-side only - Non usare le credenziali in app client
- Rigenera se compromesso - Puoi rigenerare il secret dalla dashboard
- IP Whitelist - Limita l'accesso API a IP specifici
- Scope minimi - Richiedi solo gli scope necessari