API Documentation
Build integrations with the vlastERP REST API. All endpoints are versioned under /api/v1/ and return JSON.
Interactive API Reference
Getting Started
- Create an account at app.vlasterp.com (free tier available).
- Obtain credentials — either log in via
POST /api/v1/auth/loginto get a JWT, or generate an API key from Settings → API Keys. - Make requests — pass your token as
Authorization: Bearer <token>or your API key asX-API-Key: <key>.
curl
curl -X POST https://api.vlasterp.com/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "your-password"}'javascript
const res = await fetch("https://api.vlasterp.com/api/v1/invoices", {
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json",
},
});
const { data, pagination } = await res.json();python
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
resp = requests.get(
"https://api.vlasterp.com/api/v1/clients",
headers=headers,
params={"page": 1, "per_page": 25},
)
data = resp.json()Authentication
vlastERP supports two authentication methods:
| Method | Header | Best for |
|---|---|---|
| JWT Bearer | Authorization: Bearer <token> | Browser apps, short-lived sessions |
| API Key | X-API-Key: <key> | Server-to-server, CI/CD, scripts |
JWT tokens expire after 1 hour. Use POST /api/v1/auth/refresh with your refresh token to obtain a new pair.
Rate Limits
- Authenticated: 600 requests/minute per tenant.
- Unauthenticated: 30 requests/minute per IP.
Every response includes rate-limit headers:
X-RateLimit-Limit— max requests in the windowX-RateLimit-Remaining— requests leftX-RateLimit-Reset— Unix timestamp when the window resets
When the limit is exceeded you will receive a 429 Too Many Requests response.
Pagination
All list endpoints support cursor-free offset pagination:
| Parameter | Default | Description |
|---|---|---|
page | 1 | Page number (1-based) |
per_page | 25 | Items per page (max 100) |
Responses include a pagination object:
json
{
"data": [...],
"pagination": {
"page": 1,
"per_page": 25,
"total": 142,
"total_pages": 6
}
}Errors
All errors follow a consistent JSON envelope. The code field is a machine-readable constant; message is human-readable.
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Field 'email' is required",
"details": [
{ "field": "email", "message": "must not be empty" }
]
}
}| HTTP Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request body or parameters |
| 401 | UNAUTHORIZED | Missing or invalid token/key |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | NOT_FOUND | Resource does not exist |
| 429 | RATE_LIMITED | Too many requests |
| 500 | INTERNAL_ERROR | Unexpected server error |