API Documentation

Build integrations with the vlastERP REST API. All endpoints are versioned under /api/v1/ and return JSON.

Interactive API Reference

Getting Started

  1. Create an account at app.vlasterp.com (free tier available).
  2. Obtain credentials — either log in via POST /api/v1/auth/login to get a JWT, or generate an API key from Settings → API Keys.
  3. Make requests — pass your token as Authorization: Bearer <token> or your API key as X-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:

MethodHeaderBest for
JWT BearerAuthorization: Bearer <token>Browser apps, short-lived sessions
API KeyX-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 window
  • X-RateLimit-Remaining — requests left
  • X-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:

ParameterDefaultDescription
page1Page number (1-based)
per_page25Items 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 StatusCodeMeaning
400VALIDATION_ERRORInvalid request body or parameters
401UNAUTHORIZEDMissing or invalid token/key
403FORBIDDENInsufficient permissions
404NOT_FOUNDResource does not exist
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORUnexpected server error