API Documentation

LOCURA API

v1.0

A unified REST API for integrating with the LOCURA ecosystem. Connect your ERP, WMS, or custom applications to manage clients, inventory forecasting, S&OP planning, dock scheduling, parcel monitoring, and AI-powered document generation.

Hub

16 endpoints

Identity provider, clients, files, API keys, webhooks

https://hub.locura.tech/api/v1/

Pronostico

23 endpoints

Inventory management, ABC/XYZ, demand forecasting

https://pronostico.locura.tech/api/v1/

Avisator

16 endpoints

Dock scheduling, bookings, supplier communication

https://avisator.locura.tech/api/v1/

DocMaker

13 endpoints

Controlled documents, configurable types, templates and review releases

https://docmaker.locura.tech/api/v1/

Validator

3 endpoints

Evidence-grounded compliance with tenant-scoped product and status reads for ERP, QMS and BI

https://validator.locura.tech/api/v1/

Efectiver

16 endpoints

Workforce performance & bonus, competency matrix, EU Pay Transparency (2023/970) foundation

https://efectiver.locura.tech/api/v1/

Consenso

13 endpoints

S&OP planning: demand consensus on product families, economics & budget targets, financial reconciliation, cycle freeze

https://consenso.locura.tech/api/v1/

Tracker

11 endpoints

UPS and DHL parcel monitoring, exception control, imports and ERP status writeback

https://tracker.locura.tech/api/v1/

Modeler

API planned

3D warehouse design, digital twins and autonomous layout generation; public REST API in development

https://modeler.locura.tech/api/v1/

Base URLs

Hub: https://hub.locura.tech/api/v1

Pronostico: https://pronostico.locura.tech/api/v1

Avisator: https://avisator.locura.tech/api/v1

DocMaker: https://docmaker.locura.tech/api/v1

Validator: https://validator.locura.tech/api/v1

Efectiver: https://efectiver.locura.tech/api/v1

Consenso: https://consenso.locura.tech/api/v1

Tracker: https://tracker.locura.tech/api/v1

Live service status and incident history: status.locura.tech

Authentication

All API requests require a Bearer token in the Authorization header. API keys are managed through the Hub application.

API Key Format

PrefixTypeDescription
lk_live_*Live SecretFull access to production data. Keep server-side only.
lk_test_*Test SecretSandbox environment. Safe for development and testing.
lk_pub_*PublishableRead-only access. Safe for client-side use.

Getting Your API Key

  1. Log into Hub at hub.locura.tech
  2. Navigate to Settings → API → Klucze API
  3. Click "Create new key", select scopes, and copy the key
  4. Store the key securely -- it will not be shown again

Security: API keys are stored as SHA-256 hashes. Once created, the full key cannot be retrieved. If you lose your key, revoke it and create a new one.

Usage

Include the key as a Bearer token in every request:

bash
curl -X GET "https://hub.locura.tech/api/v1/clients" \
  -H "Authorization: Bearer lk_live_abc123def456ghi789jkl012mno345"

Rate Limiting

API requests are rate-limited per API key. The limits depend on your subscription tier.

TierRequests / minBurst
Free6010 requests
Pro30050 requests
Enterprise1,000100 requests

Response Headers

Every response includes rate limit information:

HeaderDescription
X-RateLimit-LimitMaximum requests per window
X-RateLimit-RemainingRemaining requests in current window
X-RateLimit-ResetUnix timestamp when the window resets

429 Too Many Requests

json
{
  "type": "https://api.locura.tech/errors/rate-limit-exceeded",
  "title": "Rate limit exceeded",
  "status": 429,
  "detail": "You have exceeded 60 requests per minute. Please retry after 23 seconds.",
  "instance": "/api/v1/clients",
  "request_id": "req_a1b2c3d4e5f6",
  "retry_after": 23
}

Brute Force Protection

After 5 consecutive failed authentication attempts, an exponential delay is applied. The delay doubles with each additional failure, starting at 1 second up to a maximum of 60 seconds.

Error Handling

All errors follow the RFC 7807 Problem Details format, providing consistent, machine-readable error responses.

Error Response Structure

json
{
  "type": "https://api.locura.tech/errors/validation-error",
  "title": "Validation Error",
  "status": 422,
  "detail": "Field 'email' must be a valid email address.",
  "instance": "/api/v1/suppliers",
  "request_id": "req_x7y8z9a0b1c2"
}

HTTP Status Codes

StatusTitleDescription
400Bad RequestThe request body or parameters are malformed.
401UnauthorizedMissing or invalid API key.
403ForbiddenAPI key lacks the required scope for this operation.
404Not FoundThe requested resource does not exist.
409ConflictResource already exists or state conflict (e.g., double booking).
422Unprocessable EntityValidation error -- the request body failed schema validation.
429Too Many RequestsRate limit exceeded. Retry after the time indicated in the response.
500Internal Server ErrorUnexpected server error. Contact support with the request_id.

Pagination

All list endpoints support offset-based pagination with the following query parameters.

ParameterDefaultDescription
page1Page number (1-based)
per_page50Items per page (max 100)

Example Request

bash
curl "https://hub.locura.tech/api/v1/clients?page=2&per_page=25" \
  -H "Authorization: Bearer lk_live_abc123def456"

Response Format

json
{
  "data": [
    { "id": "cli_abc123", "name": "Acme Corp", "nip": "1234567890" }
  ],
  "pagination": {
    "page": 2,
    "per_page": 25,
    "total": 87
  },
  "links": {
    "next": "/api/v1/clients?page=3&per_page=25",
    "prev": "/api/v1/clients?page=1&per_page=25"
  }
}

Hub API

The Hub is the central identity provider for the LOCURA ecosystem. It manages clients, files stored in Cloudflare R2, API keys, webhooks, usage tracking, and GDPR compliance.

Base URL: https://hub.locura.tech/api/v1

Health Check

Clients

Files (R2 Storage)

API Keys

Webhooks

Usage & Audit

GDPR Compliance

Sandbox

Changelog

Pronostico API

Pronostico is the inventory management and demand forecasting engine. Push your sales, stock, and purchasing data, then run AI-powered analysis to get ABC/XYZ classifications, demand forecasts, and purchase order recommendations.

Base URL: https://pronostico.locura.tech/api/v1

Health Check

Data Push & Read

Push your operational data to Pronostico before running analysis. For datasets with 5,000 rows or fewer, processing is synchronous. Larger datasets return an async job ID. Each POST endpoint has a paired GET for reading the deduped rows back out (useful for ERP reconciliation).

Analysis

Results

Suppliers

Customers

Customer rankings derived from sales data: revenue share, order/document counts, and an automatic classification (top / regular / sporadic) based on Pareto contribution.

SKU Detail

Single-call snapshot for a SKU: classification, forecast, recommendation, weekly demand history, recent stock snapshots, and the customer breakdown — same data the dashboard SKU detail page renders.

Avisator API

Avisator handles dock scheduling and supplier communication. Manage warehouse locations, docks, time slots, and booking reservations for inbound and outbound deliveries.

Base URL: https://avisator.locura.tech/api/v1

Health Check

Locations

Bookings

Suppliers

Vehicles

Available Slots

Dock Map

DocMaker API

DocMaker is the controlled document generation platform. It produces analyses, audits, offers, contracts, presentations, articles, bonus systems, Gantt charts, transcriptions, and configurable PDF/DOCX document types. Published definitions and templates are immutable and every generated document retains both version pins. The API exposes document, governance, template, type, and job metadata without prompts or internal storage paths.

Base URL: https://docmaker.locura.tech/api/v1

Health Check

Documents

Configurable Document Types

Generation Jobs

Validator API

Validator is a universal, evidence-grounded document-compliance engine. It indexes a corpus of source documents (standards, regulations, internal procedures) and provides citation-grounded answers with sentence-level evidence to specific PDF page numbers. Multi-hop retrieval splits complex questions into sub-aspects and retrieves chunks per sub-question separately. It is currently trained on the power-tools domain (PN-EN/IEC standards, CE marking) and applies to any document-heavy field — legal, pharma, medical devices, finance — by loading that domain's source corpus.

Base URL: https://validator.locura.tech/api/v1

The public contract exposes two read-only, tenant-scoped projections for ERP, QMS and BI integrations. Create the API key in LOCURA Hub and grant only the required Validator scope. Notes, storage paths, run IDs and internal record identifiers are intentionally excluded. The compliance chat, library, audits and standards-diff remain session-authenticated web application workflows.

Health Check

Products

Compliance Status

Efectiver API

Efectiver is a multi-tenant workforce-performance and competency platform. It ingests performance events from external source systems, computes per-worker productivity, norm fulfilment and bonus analytics, and maintains a competency matrix with bus-factor risk detection — the data foundation for EU Pay Transparency (Directive 2023/970) reporting. Tenant isolation is enforced by PostgreSQL FORCE Row Level Security.

Base URL: https://efectiver.locura.tech/api/v1

Authentication differs from the rest of the LOCURA platform. Tenant provisioning uses a platform-operator admin key (x-efectiver-admin-key); ingest uses a per-source API key (x-efectiver-key); analytics endpoints use the efectiver_session cookie set by login, or an Authorization: Bearer token.

Onboarding

Request fields: tenantName (string, required, unique — 409 if taken), industry (string, required), adminEmail (valid email, required), adminPassword (string, required, min 8 chars), seedFramework (boolean, optional — seeds competency framework tasks), seedEngineDefaults (boolean, optional — seeds engine configuration defaults).

Status codes: 201 created · 400 invalid body (zod) · 401 missing/wrong admin key · 409 tenant name already exists · 500 unexpected server error.

Authentication

Sets efectiver_session cookie (httpOnly, SameSite=Lax, Secure in production, Max-Age 7d). User lookup uses the SECURITY DEFINER function lookup_user_by_email (controlled RLS bypass for pre-auth lookup).

Status codes: 200 OK · 400 missing/invalid body · 401 wrong credentials or user not found · 429 too many failed attempts (10 per 5 min per IP+email).

Ingest

The request body is a JSON array of performance event objects (source-specific schema). Maximum 50 000 events per request.

Status codes: 200 processed (see report) · 400 invalid JSON or row-level validation errors · 401 missing/invalid x-efectiver-key · 413payload exceeds 50 000 events.

Performance

Response fields: workers (WorkerResult[] — per-worker totals), heatmap (DailyCell[] — per-worker per-day earnedHours + normPct), dailyKpi (DailyKpi[] — site-level lines/workers/avgNormPct per day), trend (TrendPoint[] — avgNormPct + totalBonus per day), mdm (MdmResult | null — month-over-month, only when prevFrom + prevTo supplied). Session resolved to (tenantId, userId) via SECURITY DEFINER lookup_session.

Status codes: 200 OK · 400 missing/invalid from/to · 401 missing or expired session · 500 internal error.

Competency

Response fields: byCompetency (CompetencyCoverage[] — per-competency metrics), busFactorRisks(competency codes with peopleCount ≤ 1), uncoveredCompetencies (competency codes with peopleCount == 0), heatmap (HeatmapCell[] — employee × competency tasksHeld/tasksTotal), totals (competencies/employees/tasks counts). Status codes: 200 OK · 401 missing/expired session · 500 internal error.

AI gate: returns 503 unless EFECTIVER_AI_ENABLED=true. Enabling requires explicit cost approval and a configured provider. Status codes: 200 OK · 400 missing/invalid context · 401 not authenticated · 403 forbidden role (requires HR or Manager) · 503 AI provider not enabled.

Status codes: 200 OK · 401 not authenticated · 403 forbidden role (requires HR or Manager) · 404 suggestion not found (or belongs to another tenant — fail-closed) · 409 suggestion already approved or rejected (double-approve guard) · 500 internal error.

Clients

Status codes: 200/201 OK · 401 not authenticated · 403 GET non-allowed role / POST non-HR · 409 duplicate slug · 422 invalid name or empty derived slug.

Overhead Costs

Categories (ASCII keys): magazyn · media · transport · materialy. Status codes: 200 OK · 400 super-admin referencing a non-existent department · 401 not authenticated · 403 non-HR write or dept-scoped HR targeting another department · 404 id not in the caller department scope · 422 invalid category, periodMonth or amount.

Cost & OTIF

Ingest: rows posted to POST /api/v1/ingest/orders may include an optional client (name or slug) — the order is stamped with the resolved or created client_id (idempotent on the tenant slug). Status codes: 200 OK · 401 not authenticated · 403 role Pracownik.

Compliance

Status codes: 200 OK · 401 not authenticated · 403 role HR or Audytor required · 500 server error

Status codes: 201 created · 400 invalid JSON, missing path or domain validation · 401 not authenticated · 403 role HR required · 500 server error

Status codes: 200 OK · 400 invalid JSON, missing path.id or domain validation · 401 not authenticated · 403 role HR required · 500 server error

Status codes: 200 OK · 400 missing id · 401 not authenticated · 403 role HR required · 500 server error

Status codes: 200 OK · 200 no pay data (status payload) · 401 not authenticated · 500 server error

Status codes: 200 OK (XLSX file) · 401 not authenticated · 403 role HR or Audytor required · 500 server error

Status codes: 200 OK · 401 not authenticated · 403 role HR or Audytor required · 500 server error

Status codes: 201 created · 400 invalid JSON, missing band or domain validation · 401 not authenticated · 403 role HR required · 500 server error

Status codes: 200 OK · 400 invalid JSON, missing band.id or domain validation · 401 not authenticated · 403 role HR required · 500 server error

Status codes: 200 OK · 400 missing id · 401 not authenticated · 403 role HR required · 500 server error

Status codes: 200 OK · 401 not authenticated · 403 role HR or Audytor required · 500 server error

Configuration

Status codes: 200 OK · 401 missing or invalid session · 500 internal error

Status codes: 200 OK · 400 invalid JSON body · 401 missing or invalid session · 500 internal error

Cost Simulation

Status codes: 200 OK · 400 missing or invalid addedOrders · 401 missing or invalid session · 403 role Pracownik · 500 internal error

Departments

Status codes: 200 OK · 401 missing or invalid session · 403 not tenant super-admin

Status codes: 201 Created · 400 invalid JSON, validation error or duplicate slug · 401 missing or invalid session · 403 not tenant super-admin · 500 server error

Status codes: 200 OK · 400 invalid JSON or validation error · 401 missing or invalid session · 403 not tenant super-admin · 500 server error

Employee Portfolio

Status codes: 200 OK · 401 missing or invalid session · 403 foreign ref for role Pracownik · 404 employee not found · 500 internal error

Status codes: 200 OK (application/pdf) · 401 missing or invalid session · 403 foreign ref for role Pracownik · 404 employee not found · 500 PDF generation error

Errors & Anomalies

Status codes: 200 OK · 401 missing or invalid session · 500 internal error

Status codes: 201 created · 400 invalid JSON or validation error (employeeId/occurredOn/description/amountPln/attachmentUri) · 401 missing or invalid session · 500 internal error

Status codes: 200 OK · 400 invalid JSON or validation error (orderId) · 401 missing or invalid session · 500 internal error

Status codes: 200 OK · 401 missing or invalid session · 500 internal error

Import

Status codes: 200 OK · 401 not authenticated · 500 internal error

Status codes: 200 OK · 400 not multipart or missing file or unreadable file · 401 not authenticated · 413 file too large · 415 unsupported file type

Status codes: 200 OK · 401 not authenticated · 500 internal error

Status codes: 201 Created · 400 invalid JSON or missing name or invalid name · 401 not authenticated · 409 duplicate name · 500 internal error

Status codes: 200 OK · 401 not authenticated · 500 internal error

Status codes: 200 OK · 400 not multipart or missing file or missing mapping or invalid mapping JSON or mapping not object or mapping incomplete or processing failed · 401 not authenticated · 413 file too large or too many rows · 415 unsupported file type

Orders Ingest

Status codes: 200 OK · 400 invalid JSON body or not an array · 401 missing or invalid API key · 413 payload over 50000 rows · 422 unparseable placed_at or shipped_at

Order-Type Cutoffs

Status codes: 200 OK · 401 not authenticated or invalid session · 500 server error

Status codes: 201 Created · 400 invalid JSON or department does not exist · 401 not authenticated · 403 role not HR or wrong department · 409 cutoff already exists · 422 validation error · 500 server error

Status codes: 200 OK · 400 invalid JSON or no fields to update · 401 not authenticated · 403 role not HR · 422 validation error · 500 server error

Status codes: 200 OK · 401 not authenticated · 403 role not HR · 500 server error

Consenso API

Consenso is the S&OP planning layer of the LOCURA ecosystem. It consumes forecasts from Pronostico, rolls SKUs up to product families, and lets planners record demand consensus, planning economics and budget targets, then freeze a cycle with a full financial reconciliation snapshot.

Base URL: https://consenso.locura.tech/api/v1

Authentication: Consenso endpoints (except /health) are authenticated with the signed-in user session (LOCURA Hub SSO) and are scoped to the user's company. Bearer API-key access is on the roadmap; until then, integrate on the Pronostico side (GET /api/v1/forecasts) and use Consenso through the web UI or an authenticated session.

Health Check

Planning Cycles

Demand Consensus

Economics & Budget

Product Families

Pronostico Connection

Tracker API

Tracker monitors UPS and DHL shipments, normalizes carrier statuses, detects operational exceptions, and synchronizes status changes with stores or ERP systems. API keys are issued in Hub and must include the scope required by each operation.

Base URL: https://tracker.locura.tech/api/v1 | OpenAPI: https://tracker.locura.tech/api/docs.json | Swagger UI: https://tracker.locura.tech/api/docs

Health

Shipments

Imports

ERP & Store Ingest

Signed status callbacks

When an ingested shipment changes status, Tracker sends the JSON payload to the registered callback URL. Verify the lowercase hexadecimal HMAC-SHA256 of the raw request body before parsing it.

  • X-LOCURA-Event: event type
  • X-LOCURA-Idempotency-Key: stable delivery key for deduplication
  • X-LOCURA-Signature: HMAC-SHA256 signature of the raw body

Exceptions

Operations

Modeler

Modeler is the 3D warehouse design studio of the LOCURA ecosystem: interactive layout editing, digital twins with DWG/DXF underlays, autonomous layout generation and comprehensive PDF concept reports.

Public REST API in development. Modeler currently exposes no public /api/v1 endpoints; the application is available at modeler.locura.tech with LOCURA Hub SSO, and project sharing works through PIN-protected public view links generated in the app. Watch the changelog below for the API release.

Webhooks

Webhooks allow your application to receive real-time notifications when events occur in the LOCURA ecosystem. Events are delivered via HTTP POST to your configured endpoint with an HMAC-SHA256 signature for verification.

Available Events

EventAppDescription
avisator.booking.createdAvisatorA new booking was created
avisator.booking.approvedAvisatorA booking was approved
avisator.booking.rejectedAvisatorA booking was rejected
avisator.booking.cancelledAvisatorA booking was cancelled
avisator.booking.arrivedAvisatorVehicle arrived at the dock
avisator.booking.completedAvisatorBooking completed (loading/unloading done)
avisator.booking.no_showAvisatorVehicle did not show up
pronostico.analysis.completedPronosticoAnalysis job finished processing

Webhook Payload Format

json
{
  "id": "evt_a1b2c3d4e5",
  "type": "avisator.booking.created",
  "timestamp": "2026-03-24T10:00:00.000Z",
  "data": {
    "booking_id": "bk_e5f6g7h8",
    "location_id": "loc_a1b2c3d4",
    "dock_id": "dock_x1y2z3",
    "supplier_id": "sup_m1n2o3p4",
    "date": "2026-03-25",
    "start_time": "08:00"
  }
}

HMAC-SHA256 Signature Verification

Each webhook delivery includes an X-Locura-Signature header. Verify it by computing the HMAC-SHA256 of the raw request body using your webhook secret.

Node.js
javascript
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your Express handler:
app.post('/webhooks/locura', (req, res) => {
  const signature = req.headers['x-locura-signature'];
  const isValid = verifyWebhookSignature(
    JSON.stringify(req.body),
    signature,
    process.env.LOCURA_WEBHOOK_SECRET
  );

  if (!isValid) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Process the event
  const event = req.body;
  console.log('Received event:', event.type);

  res.status(200).json({ received: true });
});
Python
python
import hmac
import hashlib
import os
from flask import Flask, request, jsonify

app = Flask(__name__)

def verify_webhook_signature(payload, signature, secret):
    expected = hmac.new(
        secret.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

@app.route('/webhooks/locura', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('X-Locura-Signature')
    is_valid = verify_webhook_signature(
        request.get_data(as_text=True),
        signature,
        os.environ['LOCURA_WEBHOOK_SECRET']
    )

    if not is_valid:
        return jsonify({'error': 'Invalid signature'}), 401

    event = request.get_json()
    print(f"Received event: {event['type']}")

    return jsonify({'received': True}), 200

Retry Policy

Failed deliveries (non-2xx response or timeout) are retried up to 6 times with exponential backoff:

AttemptDelay
1st retry2 minutes
2nd retry4 minutes
3rd retry8 minutes
4th retry16 minutes
5th retry32 minutes
6th retry (final)64 minutes

After 6 failed attempts, the webhook is marked as disabled. You can re-enable it through the Hub UI or by deleting and recreating it via the API.

Code Examples

Complete working examples for common integration scenarios across all supported languages.

1. Authenticate and List Clients

curl
bash
# List all clients
curl "https://hub.locura.tech/api/v1/clients" \
  -H "Authorization: Bearer lk_live_abc123def456ghi789jkl012mno345"

# Search for a specific client
curl "https://hub.locura.tech/api/v1/clients?search=Acme&per_page=5" \
  -H "Authorization: Bearer lk_live_abc123def456ghi789jkl012mno345"
Python
python
import requests

API_KEY = "lk_live_abc123def456ghi789jkl012mno345"
BASE_URL = "https://hub.locura.tech/api/v1"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# List clients
response = requests.get(f"{BASE_URL}/clients", headers=headers)
data = response.json()

for client in data["data"]:
    print(f"{client['name']} (NIP: {client['nip']})")

print(f"Total: {data['pagination']['total']} clients")
JavaScript
javascript
const API_KEY = 'lk_live_abc123def456ghi789jkl012mno345';
const BASE_URL = 'https://hub.locura.tech/api/v1';

async function listClients() {
  const response = await fetch(`${BASE_URL}/clients`, {
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    }
  });

  const { data, pagination } = await response.json();

  data.forEach(client => {
    console.log(`${client.name} (NIP: ${client.nip})`);
  });

  console.log(`Total: ${pagination.total} clients`);
}

listClients();

2. Create a Dock Booking

curl
bash
# Step 1: Check available slots
curl "https://avisator.locura.tech/api/v1/slots?location_id=loc_a1b2c3d4&date=2026-03-25" \
  -H "Authorization: Bearer lk_live_abc123def456"

# Step 2: Create the booking
curl -X POST "https://avisator.locura.tech/api/v1/bookings" \
  -H "Authorization: Bearer lk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "location_id": "loc_a1b2c3d4",
    "dock_id": "dock_x1y2z3",
    "supplier_id": "sup_m1n2o3p4",
    "vehicle_type_id": "vt_tir",
    "date": "2026-03-25",
    "start_time": "09:00",
    "license_plate": "DW 12345",
    "driver_name": "Jan Kowalski",
    "cargo_description": "20 pallets of electronics"
  }'
Python
python
import requests

API_KEY = "lk_live_abc123def456ghi789jkl012mno345"
BASE_URL = "https://avisator.locura.tech/api/v1"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# Check available slots
slots = requests.get(
    f"{BASE_URL}/slots",
    headers=headers,
    params={"location_id": "loc_a1b2c3d4", "date": "2026-03-25"}
).json()

# Find first available slot
for dock in slots["data"]:
    for slot in dock["slots"]:
        if slot["available"]:
            print(f"Available: {dock['dock_name']} at {slot['start_time']}")
            break

# Create booking
booking = requests.post(
    f"{BASE_URL}/bookings",
    headers=headers,
    json={
        "location_id": "loc_a1b2c3d4",
        "dock_id": "dock_x1y2z3",
        "supplier_id": "sup_m1n2o3p4",
        "vehicle_type_id": "vt_tir",
        "date": "2026-03-25",
        "start_time": "09:00",
        "license_plate": "DW 12345",
        "driver_name": "Jan Kowalski",
        "cargo_description": "20 pallets of electronics"
    }
).json()

print(f"Booking created: {booking['data']['id']}")
JavaScript
javascript
const API_KEY = 'lk_live_abc123def456ghi789jkl012mno345';
const BASE_URL = 'https://avisator.locura.tech/api/v1';

const headers = {
  'Authorization': `Bearer ${API_KEY}`,
  'Content-Type': 'application/json'
};

async function createBooking() {
  // Check available slots
  const slotsRes = await fetch(
    `${BASE_URL}/slots?location_id=loc_a1b2c3d4&date=2026-03-25`,
    { headers }
  );
  const slots = await slotsRes.json();

  // Create the booking
  const bookingRes = await fetch(`${BASE_URL}/bookings`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      location_id: 'loc_a1b2c3d4',
      dock_id: 'dock_x1y2z3',
      supplier_id: 'sup_m1n2o3p4',
      vehicle_type_id: 'vt_tir',
      date: '2026-03-25',
      start_time: '09:00',
      license_plate: 'DW 12345',
      driver_name: 'Jan Kowalski',
      cargo_description: '20 pallets of electronics'
    })
  });

  const booking = await bookingRes.json();
  console.log(`Booking created: ${booking.data.id}`);
}

createBooking();

3. Push Sales Data and Run Analysis

curl
bash
# Step 1: Push sales data
curl -X POST "https://pronostico.locura.tech/api/v1/data/sales" \
  -H "Authorization: Bearer lk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "rows": [
      {"sku": "SKU-001", "date": "2026-01-15", "quantity": 120, "revenue": 4560.00},
      {"sku": "SKU-001", "date": "2026-02-15", "quantity": 135, "revenue": 5130.00},
      {"sku": "SKU-002", "date": "2026-01-15", "quantity": 45, "revenue": 1350.00}
    ]
  }'

# Step 2: Start analysis
curl -X POST "https://pronostico.locura.tech/api/v1/analysis/run" \
  -H "Authorization: Bearer lk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{"type": "full"}'

# Step 3: Check job status (poll until completed)
curl "https://pronostico.locura.tech/api/v1/analysis/job_q1r2s3t4" \
  -H "Authorization: Bearer lk_live_abc123def456"

# Step 4: Get results
curl "https://pronostico.locura.tech/api/v1/analysis/job_q1r2s3t4/results" \
  -H "Authorization: Bearer lk_live_abc123def456"
Python
python
import requests
import time

API_KEY = "lk_live_abc123def456ghi789jkl012mno345"
BASE_URL = "https://pronostico.locura.tech/api/v1"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# Step 1: Push sales data
upload = requests.post(
    f"{BASE_URL}/data/sales",
    headers=headers,
    json={
        "rows": [
            {"sku": "SKU-001", "date": "2026-01-15", "quantity": 120, "revenue": 4560.00},
            {"sku": "SKU-001", "date": "2026-02-15", "quantity": 135, "revenue": 5130.00},
            {"sku": "SKU-002", "date": "2026-01-15", "quantity": 45, "revenue": 1350.00}
        ]
    }
).json()
print(f"Upload: {upload['data']['upload_id']}")

# Step 2: Start analysis
analysis = requests.post(
    f"{BASE_URL}/analysis/run",
    headers=headers,
    json={"type": "full"}
).json()
job_id = analysis["data"]["job_id"]
print(f"Analysis started: {job_id}")

# Step 3: Poll for completion
while True:
    status = requests.get(
        f"{BASE_URL}/analysis/{job_id}",
        headers=headers
    ).json()

    if status["data"]["status"] == "completed":
        print("Analysis completed!")
        break
    elif status["data"]["status"] == "failed":
        print("Analysis failed!")
        break

    print(f"Progress: {status['data']['progress']}%")
    time.sleep(5)

# Step 4: Get results
results = requests.get(
    f"{BASE_URL}/analysis/{job_id}/results",
    headers=headers
).json()

summary = results["data"]["summary"]
print(f"Analyzed {summary['total_skus']} SKUs")
print(f"Recommendations: {summary['recommendations_count']}")
JavaScript
javascript
const API_KEY = 'lk_live_abc123def456ghi789jkl012mno345';
const BASE_URL = 'https://pronostico.locura.tech/api/v1';

const headers = {
  'Authorization': `Bearer ${API_KEY}`,
  'Content-Type': 'application/json'
};

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function runAnalysis() {
  // Step 1: Push sales data
  const upload = await fetch(`${BASE_URL}/data/sales`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      rows: [
        { sku: 'SKU-001', date: '2026-01-15', quantity: 120, revenue: 4560.00 },
        { sku: 'SKU-001', date: '2026-02-15', quantity: 135, revenue: 5130.00 },
        { sku: 'SKU-002', date: '2026-01-15', quantity: 45, revenue: 1350.00 }
      ]
    })
  }).then(r => r.json());

  console.log(`Upload: ${upload.data.upload_id}`);

  // Step 2: Start analysis
  const analysis = await fetch(`${BASE_URL}/analysis/run`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ type: 'full' })
  }).then(r => r.json());

  const jobId = analysis.data.job_id;
  console.log(`Analysis started: ${jobId}`);

  // Step 3: Poll for completion
  let status;
  do {
    await sleep(5000);
    status = await fetch(`${BASE_URL}/analysis/${jobId}`, { headers })
      .then(r => r.json());
    console.log(`Progress: ${status.data.progress}%`);
  } while (status.data.status !== 'completed' && status.data.status !== 'failed');

  // Step 4: Get results
  const results = await fetch(
    `${BASE_URL}/analysis/${jobId}/results`,
    { headers }
  ).then(r => r.json());

  const summary = results.data.summary;
  console.log(`Analyzed ${summary.total_skus} SKUs`);
  console.log(`Recommendations: ${summary.recommendations_count}`);
}

runAnalysis();

4. Check Document Generation Status

Python
python
import requests
import time

API_KEY = "lk_live_abc123def456ghi789jkl012mno345"
BASE_URL = "https://docmaker.locura.tech/api/v1"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# List active generation jobs
jobs = requests.get(
    f"{BASE_URL}/jobs",
    headers=headers,
    params={"status": "processing"}
).json()

for job in jobs["data"]:
    print(f"Job {job['id']}: {job['document_type']} - {job['progress']}%")

# Wait for a specific job to complete
job_id = "gjob_e5f6g7h8"
while True:
    job = requests.get(
        f"{BASE_URL}/jobs/{job_id}",
        headers=headers
    ).json()

    status = job["data"]["status"]
    progress = job["data"]["progress"]
    step = job["data"].get("current_step", "")

    print(f"[{progress}%] {step}")

    if status == "completed":
        doc_id = job["data"]["document_id"]
        print(f"Document ready: {doc_id}")

        # Download the document
        response = requests.get(
            f"{BASE_URL}/documents/{doc_id}/download",
            headers=headers
        )
        with open("document.pdf", "wb") as f:
            f.write(response.content)
        print("Downloaded: document.pdf")
        break
    elif status == "failed":
        print("Generation failed!")
        break

    time.sleep(3)

Changelog

v1.5.02026-07-12

Tracker shipment monitoring API

  • Tracker API: 11 operations for UPS/DHL shipment monitoring, exception handling, imports and operational usage.
  • POST /api/v1/ingest/orders: idempotent store, ERP and WMS shipment ingestion with allowlisted callback URLs.
  • Signed source callbacks use HMAC-SHA256, stable idempotency keys and retryable outbox delivery.
  • OpenAPI 3.1 JSON and Swagger UI are published by Tracker.
v1.4.02026-07-11

Consenso joins the API directory; full ecosystem coverage

  • Consenso API — 13 operations for S&OP planning: cycles with Pronostico baseline ingest, demand consensus, planning economics & budget targets, product families and per-tenant Pronostico connection. Session-authenticated (Hub SSO); GET /api/v1/health is public.
  • Modeler listed in the directory — 3D warehouse design studio; public REST API in development.
  • Pronostico: documented POST /api/v1/data/models (model grouping, carton size, model-level MOQ) and POST /api/v1/data/sku-moq (per-SKU minimum order quantities).
v1.3.02026-05-31

Efectiver joins the API directory

  • Efectiver API — 8 endpoints for multi-tenant workforce performance, bonus and competency analytics (foundation for EU Pay Transparency, Directive 2023/970).
  • POST /api/v1/onboarding — provision a tenant (admin-key authenticated).
  • POST /api/v1/auth/login + /logout — session cookie auth.
  • POST /api/v1/ingest/{source} — per-source API-key push connector (up to 50 000 events/request).
  • GET /api/v1/performance — per-worker totals, heatmap, daily KPIs, trend, optional MoM.
  • GET /api/v1/competency/coverage + POST /competency/suggest + /suggest/{id}/approve — competency matrix, bus-factor risk and human-in-the-loop AI suggestions.
v1.2.02026-05-30

Validator joins the API directory

  • Validator API — universal evidence-grounded document-compliance engine (cited answers vs standards, laws & procedures); currently trained on the power-tools domain, applicable to legal, pharma and any document-heavy field.
  • GET /api/v1/health — public health check with db + embeddings status.
  • Compliance chat, document library, audit and source-diff are session-authenticated in the web UI; public REST endpoints are on the roadmap.
v1.1.02026-04-22

Pronostico: read-side endpoints

  • GET /api/v1/data/sales/list — read deduped sales transactions with SKU/date/customer filters and pagination.
  • GET /api/v1/data/stock/snapshots — stock snapshot history; latest_only=1 for current inventory only.
  • GET /api/v1/customers + /{id} — customer rankings with revenue/order stats and per-SKU breakdown.
  • GET /api/v1/sku/{sku} — single-call snapshot: classification + forecast + recommendation + history + customers.
  • Premise: every dataset Pronostico stores is now retrievable via the API for ERP reconciliation.
v1.3.02026-07-13

DocMaker Control Plane

  • DocMaker API now exposes 13 read operations.
  • Configurable document type registry with immutable definition versions, dynamic forms, validation rules, output formats, and template pins.
  • Versioned template catalog and governance release snapshots remain available through the same tenant-scoped document read permission.
  • Public responses exclude prompts and internal storage paths.
v1.0.02026-03-24

Initial Release

  • REST API v1 with unified authentication across all LOCURA apps
  • Hub API -- 16 endpoints: clients, files (R2), API keys, webhooks, usage, GDPR, sandbox
  • Pronostico API -- 15 endpoints: data push (sales, stock, POs, prices), analysis, classifications, forecasts, recommendations, suppliers (extended to 20 in v1.1.0)
  • Avisator API -- 16 endpoints: locations, docks, bookings, suppliers, vehicles, slots, dock map
  • DocMaker API -- 6 endpoints: documents, download, generation jobs
  • Validator API -- 1 public endpoint: health (compliance chat, library, audit, standards-diff endpoints on roadmap)
  • Webhook system with HMAC-SHA256 verification and exponential retry backoff
  • Rate limiting with 3 tiers (free: 60/min, pro: 300/min, enterprise: 1000/min)
  • RFC 7807 Problem Details error format
  • Sandbox environment with test keys (lk_test_*)
  • Swagger UI available for all 4 applications