Authentication

The Sensos REST API uses OAuth 2.0 / JSON Web Token (JWT) authentication to secure all requests. Client applications authenticate using Machine-to-Machine (M2M) application credentials provisioned at the tenant level.


Generating an Access Token

To authenticate, send an HTTP POST request containing your tenantId, applicationId, and applicationSecret to the token generation endpoint:

Endpoint

POST https://api.sensos.io/v1/applications/token
Content-Type: application/json

Request Body

{
  "tenantId": "YOUR_TENANT_ID",
  "applicationId": "YOUR_APPLICATION_ID",
  "applicationSecret": "YOUR_APPLICATION_SECRET"
}

Response

The response returns your signed JWT access token and its validity period in seconds (24 hours / 86,400 seconds):

{
  "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresIn": 86400
}

Code Examples

curl -X POST "https://api.sensos.io/v1/applications/token" \
     -H "Content-Type: application/json" \
     -d '{
           "tenantId": "YOUR_TENANT_ID",
           "applicationId": "YOUR_APPLICATION_ID",
           "applicationSecret": "YOUR_APPLICATION_SECRET"
         }'
import requests

def get_sensos_token(tenant_id: str, app_id: str, app_secret: str) -> str:
    url = "https://api.sensos.io/v1/applications/token"
    payload = {
        "tenantId": tenant_id,
        "applicationId": app_id,
        "applicationSecret": app_secret
    }
    response = requests.post(url, json=payload)
    response.raise_for_status()
    data = response.json()
    return data["accessToken"]
interface TokenResponse {
  accessToken: string;
  expiresIn: number;
}

async function getSensosToken(tenantId: string, appId: string, appSecret: string): Promise<string> {
  const response = await fetch("https://api.sensos.io/v1/applications/token", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      tenantId,
      applicationId: appId,
      applicationSecret: appSecret
    })
  });

  if (!response.ok) {
    throw new Error(`Auth failed with status: ${response.status}`);
  }

  const data = (await response.json()) as TokenResponse;
  return data.accessToken;
}
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

public async Task<string> GetSensosTokenAsync(string tenantId, string appId, string appSecret)
{
    using var client = new HttpClient();
    var payload = new { tenantId, applicationId = appId, applicationSecret = appSecret };
    var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
    
    var response = await client.PostAsync("https://api.sensos.io/v1/applications/token", content);
    response.EnsureSuccessStatusCode();
    
    var json = await response.Content.ReadAsStringAsync();
    using var doc = JsonDocument.Parse(json);
    return doc.RootElement.GetProperty("accessToken").GetString();
}

Using the Access Token

Include the token in the Authorization header of all subsequent API requests, prefixed with Bearer and a single space:

GET https://api.sensos.io/v1/accounts/{accountId}/shipments
Authorization: Bearer <YOUR_ACCESS_TOKEN>
Accept: application/json

Token Lifecycle & Caching Best Practices

  • Cache the Token: Tokens are valid for 24 hours (86,400 seconds). Cache the token in memory or a shared distributed cache (e.g. Redis). Do not request a new token per API call.
  • Proactive Refresh: Implement proactive refresh at ~23 hours (before expiration) or intercept 401 Unauthorized responses to refresh the token and retry the failed call once.
  • Credential Storage: Never commit applicationSecret values into source control or client-side code. Use environment variables or cloud secret managers (e.g. AWS Secrets Manager, Azure Key Vault, HashiCorp Vault).

Error Handling

If authentication fails due to invalid credentials, missing headers, or expired tokens, the API returns HTTP 401 Unauthorized:

{
  "error": {
    "code": "Unauthorized",
    "message": "Invalid application credentials or expired access token."
  }
}

Did this page help you?