API Documentation

REST API for external integration. Access articles, stock, orders, receptions and more via Bearer token.

Login
Overview

The API allows external systems (ERP, mobile apps) to read data from 3PL Client. Authentication uses Bearer tokens (Laravel Sanctum). All data endpoints require authentication.

Base URL: https://flowscmc.eu/api

Machine-readable OpenAPI 3.0 specification (paths aligned with this API): https://flowscmc.eu/openapi.json

Authentication

Obtain a Bearer token by sending email and password:

POST https://flowscmc.eu/api/auth/token
Content-Type: application/json

{
  "email": "your@email.com",
  "password": "your-password"
}

// Response:
{
  "token": "1|abc123...",
  "user": { "id": 1, "name": "...", "email": "..." }
}

Use the token in all subsequent requests:

Authorization: Bearer 1|abc123...

To revoke the current token (logout):

POST https://flowscmc.eu/api/auth/revoke
Authorization: Bearer 1|abc123...
Company context

To filter data by company, send the optional header:

X-Company-Id: 123

The user must have access to the specified company. Without this header, super-admins see all companies; regular users see their primary company.

UM 3PL quantities on order lines

When defining an article, the first unit of measure in the system (field um3pl, UM 3PL in the UI) must be the one used for physical warehouse handling. UM2 and UM3 are for higher packaging levels when needed.

Purchase orders, sales orders, receptions, and returns use line fields um3pl and quantity_um3pl. You may send decimals with a comma (e.g. 1,5); the API normalizes to a dot before validation.

If the article requires whole-number UM 3PL quantities, or the 3PL stock-unit catalog marks that UM code as integer-only, quantity_um3pl must be a whole number. Otherwise validation fails with the standard error payload.

eTSM inbound (shared Bearer, not Sanctum)

Configure ETSM_INBOUND_BEARER_TOKEN in the environment. Use Authorization: Bearer <that token>. For creating receptions, call POST /api/integrations/etsm/receptions with the same JSON body as POST /api/receptions and header X-Company-Id set to the client company id. GET /api/integrations/etsm/ping verifies the token.

GET https://flowscmc.eu/api/integrations/etsm/ping
Authorization: Bearer <ETSM_INBOUND_BEARER_TOKEN>

POST https://flowscmc.eu/api/integrations/etsm/receptions
Authorization: Bearer <ETSM_INBOUND_BEARER_TOKEN>
X-Company-Id: 123
Content-Type: application/json

{ ... same JSON as POST /api/receptions ... }
Pagination

List endpoints support pagination via query parameters:

?page=1&per_page=25

Default per_page: 25. Maximum per_page: 100 (200 for stock). Response includes meta and links.

Available endpoints
Method Endpoint Description
GET /api/health Health check for monitoring (no auth required)
GET /api/integrations/etsm/ping eTSM connectivity check (shared Bearer; 503 if token not configured)
POST /api/integrations/etsm/receptions Create reception from eTSM (X-Company-Id required; same rules as /api/receptions)
GET /api/articles List articles (paginated)
GET /api/articles/{id} Article details
GET /api/stock Stock levels (paginated, max 200/page)
GET /api/sales-orders Sales orders (paginated)
GET /api/sales-orders/{id} Sales order details
GET /api/purchase-orders Purchase orders (paginated)
GET /api/purchase-orders/{id} Purchase order details
GET /api/receptions Receptions (paginated)
GET /api/receptions/{id} Reception details
GET /api/returns Returns (limit 100)
GET /api/returns/{id} Return details
GET /api/webhooks Webhooks list
GET /api/webhooks/{id} Webhook details
GET /graphql GraphQL endpoint – Query articles and other data via GraphQL. Requires Bearer token and X-Company-Id header.
GraphQL endpoint

Query articles and other data via GraphQL. Requires Bearer token and X-Company-Id header.

Base URL: https://flowscmc.eu/graphql

Example query – list articles:

POST https://flowscmc.eu/graphql
Authorization: Bearer YOUR_TOKEN
X-Company-Id: 1
Content-Type: application/json

{
  "query": "{ articles(limit: 10) { id article_code description } }"
}

Use the same Bearer token and X-Company-Id header as for REST endpoints.

Health check (JSON)

GET /api/health returns the same JSON as GET /health and GET /up (no auth). The body includes aggregate checks, heartbeats (per scheduler name, last ping, ok), integrations and modules. If the heartbeats table is empty, items contains a placeholder row for cron and no_records is true until the scheduler runs heartbeat:ping.

{
  "status": "healthy",
  "app": { "name": "3PL", "env": "production" },
  "urls": {
    "app": "https://example.com",
    "api": "https://example.com/api"
  },
  "checks": {
    "database": true,
    "cache": true,
    "queue": true,
    "redis": true,
    "storage": true,
    "storage_public": true,
    "heartbeat": true
  },
  "heartbeats": {
    "stale_after_minutes": 15,
    "no_records": false,
    "items": [
      { "name": "cron", "last_ping_at": "2026-04-09T12:00:00.123456Z", "last_ping_at_ms": 1775736000123, "ok": true }
    ]
  },
  "integrations": { "anaf": true },
  "modules": [ { "slug": "api", "name": "API" } ],
  "timestamp": "2026-04-09T12:00:00+00:00"
}

urls.app and urls.api come from APP_URL (base app and /api). Prometheus: append ?format=prometheus. Web UI with live heartbeats: Platform → Health (super-admin).

Example request
curl -X GET "https://flowscmc.eu/api/articles" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Company-Id: 1" \
  -H "Accept: application/json"
Rate limiting
  • POST /api/auth/token: 10 requests per minute
  • Data endpoints: 60 requests per minute
API Playground

Test API endpoints directly from this page. First obtain a token, then select an endpoint and send the request.

1
Obtain token
2
Test endpoint
Ready to integrate?

Log in to create Bearer tokens and access the API.

Login

We use essential cookies for the application to work. Optional cookies help us improve the experience. Learn more