Transipal API Documentation
Quick Start Guide
Get started with the Transipal API in 5 simple steps:
Authenticate
Log in with your credentials to receive access and refresh tokens.
POST /api/login
Use Access Token
Include the access token in the Authorization header of all requests.
Authorization: Bearer TOKEN
Refresh Tokens
Use the refresh token to get new access tokens without re-authenticating.
POST /api/token/refresh
List Warehouses
Get list of warehouses you have access to. Supports filtering and pagination.
GET /api/warehouses
Access Warehouse Data
Use warehouse subdomains to access warehouse-specific endpoints.
https://{warehouse}.demo.transipal.com/api/missions
Authentication
The Transipal API uses OAuth 2.0-style authentication with access tokens and refresh tokens. Authenticate once to receive both tokens, then use the refresh token to maintain seamless access.
Login Endpoint
{
"email": "user@example.com",
"password": "your_password",
"device_id": "iPhone-12-Pro-Max-ABC123"
}
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh_token": "abc123def456...",
"token_type": "Bearer",
"expires_in": 3600
}
curl -X POST "https://developer.demo.transipal.com/api/login" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "your_password",
"device_id": "iPhone-12-Pro-Max-ABC123"
}'
Important
- Access tokens expire after 1 hour (3600 seconds)
- Refresh tokens expire after 30 days
- Tokens are global and work across all warehouses you have access to
- Store refresh tokens securely - they allow access to your account
- device_id (optional) - Provide a device identifier to track and manage refresh tokens per device. Useful for device management features.
Token Management
Access Tokens
Access tokens are short-lived JWT tokens used to authenticate API requests.
- Expires after 1 hour (3600 seconds)
- Must be included in
Authorizationheader - Format:
Bearer {access_token} - Global - works across all warehouses
curl -X GET "https://{warehouse}.demo.transipal.com/api/missions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Refresh Tokens
Refresh tokens are long-lived tokens used to obtain new access tokens without re-authenticating.
- Expires after 30 days
- Used only with
/api/token/refreshendpoint - Automatically rotated on each refresh (old token revoked)
- Must be stored securely (never expose in client-side code)
curl -X POST "https://developer.demo.transipal.com/api/token/refresh" \
-H "Content-Type: application/json" \
-d '{"refresh_token": "YOUR_REFRESH_TOKEN"}'
Token Rotation
When you refresh your access token, the system automatically:
- Revokes your old refresh token
- Issues a new refresh token
- Returns both the new access token and new refresh token
Important: Always store the new refresh token and discard the old one. Using a revoked refresh token will result in a 401 error.
API Endpoints Reference
Login
/api/login
Authenticate and receive access and refresh tokens.
Refresh Token
/api/token/refresh
Exchange refresh token for new access and refresh tokens.
List Warehouses
/api/warehouses
Get paginated list of warehouses you have access to. Supports filtering by name and subdomain.
Warehouse Missions
{warehouse}.demo.transipal.com/api/missions
Access missions for a specific warehouse.
Code Examples
Complete Authentication Flow
# 1. Login
curl -X POST "https://developer.demo.transipal.com/api/login" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "password", "device_id": "iPhone-12-Pro-Max-ABC123"}'
# Response contains access_token and refresh_token
# Store both tokens securely
# 2. List available warehouses (with filtering and pagination)
curl -X GET "https://developer.demo.transipal.com/api/warehouses?name=boudry&page=1&itemsPerPage=10" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 3. Use access token for API requests
curl -X GET "https://{warehouse}.demo.transipal.com/api/missions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 4. Refresh token when access token expires
curl -X POST "https://developer.demo.transipal.com/api/token/refresh" \
-H "Content-Type: application/json" \
-d '{"refresh_token": "YOUR_REFRESH_TOKEN"}'
# Response contains new access_token and refresh_token
# Update your stored tokens
JavaScript/TypeScript Example
// Store tokens securely (use secure storage, not localStorage for production)
let accessToken = null;
let refreshToken = null;
// 1. Login
async function login(email, password, deviceId = null) {
const response = await fetch('https://developer.demo.transipal.com/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email,
password,
...(deviceId && { device_id: deviceId })
})
});
const data = await response.json();
accessToken = data.access_token;
refreshToken = data.refresh_token;
return data;
}
// 2. List available warehouses
async function getWarehouses(filters = {}, page = 1, itemsPerPage = 30) {
const params = new URLSearchParams({
page: page.toString(),
itemsPerPage: itemsPerPage.toString(),
...filters
});
const response = await fetch(
`https://developer.demo.transipal.com/api/warehouses?${params}`,
{
headers: { 'Authorization': `Bearer ${accessToken}` }
}
);
if (response.status === 401) {
await refreshAccessToken();
return getWarehouses(filters, page, itemsPerPage);
}
return response.json();
}
// 3. Make authenticated request
async function getMissions(warehouseSubdomain) {
const response = await fetch(
`https://${warehouseSubdomain}.demo.transipal.com/api/missions`,
{
headers: { 'Authorization': `Bearer ${accessToken}` }
}
);
if (response.status === 401) {
// Token expired, refresh it
await refreshAccessToken();
// Retry request
return getMissions(warehouseSubdomain);
}
return response.json();
}
// 4. Refresh access token
async function refreshAccessToken() {
const response = await fetch('https://developer.demo.transipal.com/api/token/refresh', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refresh_token: refreshToken })
});
const data = await response.json();
accessToken = data.access_token;
refreshToken = data.refresh_token; // New refresh token (old one is revoked)
return data;
}
Python Example
import requests
class TransipalAPI:
def __init__(self, base_url='https://developer.demo.transipal.com'):
self.base_url = base_url
self.access_token = None
self.refresh_token = None
def login(self, email, password, device_id=None):
"""Authenticate and get tokens"""
payload = {'email': email, 'password': password}
if device_id:
payload['device_id'] = device_id
response = requests.post(
f'{self.base_url}/api/login',
json=payload
)
response.raise_for_status()
data = response.json()
self.access_token = data['access_token']
self.refresh_token = data['refresh_token']
return data
def refresh_access_token(self):
"""Refresh access token using refresh token"""
response = requests.post(
f'{self.base_url}/api/token/refresh',
json={'refresh_token': self.refresh_token}
)
response.raise_for_status()
data = response.json()
self.access_token = data['access_token']
self.refresh_token = data['refresh_token'] # New refresh token
return data
def get_warehouses(self, name=None, subdomain=None, page=1, items_per_page=30):
"""Get list of warehouses with optional filtering and pagination"""
params = {'page': page, 'itemsPerPage': items_per_page}
if name:
params['name'] = name
if subdomain:
params['subdomain'] = subdomain
headers = {'Authorization': f'Bearer {self.access_token}'}
response = requests.get(
f'{self.base_url}/api/warehouses',
headers=headers,
params=params
)
if response.status_code == 401:
self.refresh_access_token()
headers['Authorization'] = f'Bearer {self.access_token}'
response = requests.get(
f'{self.base_url}/api/warehouses',
headers=headers,
params=params
)
response.raise_for_status()
return response.json()
def get_missions(self, warehouse_subdomain):
"""Get missions for a warehouse"""
headers = {'Authorization': f'Bearer {self.access_token}'}
response = requests.get(
f'https://{warehouse_subdomain}.demo.transipal.com/api/missions',
headers=headers
)
if response.status_code == 401:
# Token expired, refresh and retry
self.refresh_access_token()
headers['Authorization'] = f'Bearer {self.access_token}'
response = requests.get(
f'https://{warehouse_subdomain}.demo.transipal.com/api/missions',
headers=headers
)
response.raise_for_status()
return response.json()
# Usage
api = TransipalAPI()
api.login('user@example.com', 'password', device_id='iPhone-12-Pro-Max-ABC123')
# Get warehouses (with filtering)
warehouses = api.get_warehouses(name='boudry', page=1, items_per_page=10)
# Get missions for a warehouse
missions = api.get_missions('{warehouse}')
Warehouse Context
The Transipal API uses subdomain-based routing to determine warehouse context. Your tokens are global, but API requests are scoped to specific warehouses via subdomains.
How It Works
- Log in once from any subdomain (developer, www, or warehouse subdomain)
- Receive global access and refresh tokens
- Use warehouse subdomains to access warehouse-specific data
- The same tokens work for all warehouses you have access to
Examples
https://{warehouse}.demo.transipal.com/api/missions
https://{warehouse}.demo.transipal.com/api/missions
https://developer.demo.transipal.com/api/warehouses
# With filtering: ?name=boudry
# With pagination: ?page=1&itemsPerPage=10
Important
Replace the warehouse subdomain in the URL to access different warehouses. The /api/warehouses endpoint is a native API Platform collection that:
- Returns only warehouses you have access to (automatically filtered by your permissions)
- Supports filtering by
nameandsubdomain(partial matching) - Supports pagination with
pageanditemsPerPageparameters - Returns a standard collection response format
Warehouses Endpoint
The /api/warehouses endpoint is a native API Platform collection that returns warehouses you have access to. It supports filtering, pagination, and automatic access control.
Endpoint Details
name- Filter by warehouse name (partial match)subdomain- Filter by warehouse subdomain (partial match)page- Page number for pagination (default: 1)itemsPerPage- Number of items per page (default: 30, max: 100)order[name]- Sort by name (asc/desc)order[subdomain]- Sort by subdomain (asc/desc)
Example Requests
curl -X GET "https://developer.demo.transipal.com/api/warehouses" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
curl -X GET "https://developer.demo.transipal.com/api/warehouses?name=boudry" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
curl -X GET "https://developer.demo.transipal.com/api/warehouses?page=1&itemsPerPage=10" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response Format
[
{
"id": 1,
"name": "Boudry",
"subdomain": "boudry"
},
{
"id": 2,
"name": "Geneva",
"subdomain": "geneva"
}
]
Automatic Access Control
Rate Limiting
The Transipal API implements rate limiting to ensure fair usage and protect the service from abuse. All API requests are subject to rate limits.
Rate Limits
| Requests per user | 200 requests per minute |
| Pagination limit | Maximum 100 items per page |
| Default pagination | 30 items per page |
Response Headers
Every API response includes rate limit headers:
X-RateLimit-Limit |
Maximum requests allowed (200) |
X-RateLimit-Remaining |
Requests remaining in current window |
X-RateLimit-Reset |
Unix timestamp when the limit resets |
When Rate Limited
When you exceed the rate limit, the API returns a 429 Too Many Requests response:
{
"error": "Too Many Requests",
"message": "API rate limit exceeded. Please wait before making more requests.",
"retry_after": 1704708000
}
The Retry-After header indicates how many seconds to wait before making another request.
Best Practices
- Monitor rate limit headers - Track
X-RateLimit-Remainingto avoid hitting the limit - Implement exponential backoff - When rate limited, wait progressively longer between retries
- Cache responses - Reduce API calls by caching data that doesn't change frequently
- Use pagination wisely - Request only the data you need with appropriate page sizes
Error Handling
| Status Code | Error | Description | Solution |
|---|---|---|---|
| 400 | Bad Request | Invalid request format or missing required fields | Check request body and headers |
| 401 | Unauthorized | Invalid, expired, or missing access token | Refresh your access token or re-authenticate |
| 403 | Forbidden | Valid token but insufficient permissions | Check your user roles and permissions |
| 404 | Not Found | Resource doesn't exist | Verify the endpoint URL and resource ID |
| 429 | Too Many Requests | Rate limit exceeded | Wait and retry after the Retry-After header value |
| 500 | Internal Server Error | Server-side error | Contact support if the issue persists |
Error Response Format
{
"error": "error_code",
"message": "Human-readable error message"
}
Best Practices
Security
- Store refresh tokens securely - Use secure storage (Keychain on iOS, Keystore on Android)
- Never expose tokens in client-side code - Especially in web browsers
- Use HTTPS only - Never send tokens over unencrypted connections
- Rotate tokens regularly - Refresh tokens before they expire
- Revoke tokens on logout - Implement token revocation in your app
Performance
- Cache access tokens - Store them in memory for the session
- Refresh proactively - Refresh tokens before they expire (e.g., at 50 minutes)
- Handle 401 errors gracefully - Automatically refresh and retry failed requests
- Batch requests when possible - Reduce the number of API calls
- Use pagination - Don't fetch all data at once
- Respect rate limits - Monitor
X-RateLimit-Remainingheaders to avoid 429 errors
Interactive API Documentation
Try API requests directly from your browser with Swagger UI. Test endpoints, see live responses, and explore the full API.
View Interactive Documentation