# Meet the API

<div style="text-align: justify;">

VeloxFactory ships with a fully capable REST API — and it is not an afterthought. Every action you can perform in the frontend can also be performed via the API, because **the frontend and the API share the same controller methods**. There is no separate implementation, no feature gap, no second-class citizen.

This makes the API a genuine alternative to the UI, not just an integration bolt-on. Automate report rendering in your CI pipeline, trigger prints from your ERP, manage report configurations programmatically — all with the same logic that powers the frontend you already know.

<div style="border-left: 4px solid #5fc75d; background: #f6fdf6; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
ℹ️ For the full endpoint reference including all parameters and response schemas, explore the live demo API documentation at <a href="https://demo.veloxfactory.kiwi-software.dev" target="_blank">demo.veloxfactory.kiwi-software.dev</a>.
<p style="margin: 6px 0 0 0;"><strong>Login:</strong> <code>demo@velox.factory</code> &nbsp;·&nbsp; <strong>Password:</strong> <code>demo</code></p>
</div>

---

<h3 style="color: #203671; margin-top: 2.2em;">Authentication</h3>

The API uses **token-based authentication** via Laravel Sanctum. Every request must include a Bearer token in the `Authorization` header.

```http
Authorization: Bearer your-api-token
```

Tokens are created and managed per user — either from the user management section in the frontend, or via the API itself (`POST /api/v1/user/{id}/create-token`). Each token can be revoked at any time. A revoked token is rejected immediately — there is no grace period.

```json
{
  "success": false,
  "errors": ["This API token has been revoked."],
  "status": 401
}
```

The audit trail records which token was used for every create and update operation across all models, so every API action is fully traceable.

---

<h3 style="color: #203671; margin-top: 2.2em;">Base URL</h3>

All API v1 endpoints are prefixed with:

```
/api/v1/
```

---

<h3 style="color: #203671; margin-top: 2.2em;">Response Structure</h3>

All API responses follow a consistent envelope format.

**Success:**

```json
{
  "success": true,
  "count": 1,
  "data": { ... },
  "meta": [],
  "status": 200
}
```

**Error:**

```json
{
  "success": false,
  "errors": ["Descriptive error message"],
  "meta": {},
  "status": 404
}
```

The `count` field reflects the number of records in `data` — `1` for single-record responses, the actual number of returned records for collections. The `meta` field carries contextual information such as the `traceId` of a render run.

---

<h3 style="color: #203671; margin-top: 2.2em;">Query Parameters</h3>

Most `GET` endpoints and the render endpoint share a common set of query parameters that control what is included in the response. They are additive — combine them freely.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `limit` | integer | `25` | Maximum records to return. Set to `0` for all. |
| `withRelations` | boolean | `false` | Include related models (e.g. parameters, fields, resources on a ReportConfig). |
| `recursiveRelations` | boolean | `false` | Include nested relations within relations. |
| `withMedia` | boolean | `false` | Include Base64-encoded file content, previews, and thumbnails. |
| `withAudit` | boolean | `false` | Include the audit segment on each record (timestamps, users, token, method). |

**Example** — retrieve a single report config with all relations, media, and audit data:

```http
GET /api/v1/report-config/1?withRelations=true&withMedia=true&withAudit=true
```

<h4 style="color: #203671; margin-top: 1.4em;">Audit Segment</h4>

When `withAudit=true` is set, every record in the response carries an `audit` block:

```json
"audit": {
  "createdAt": "2026-05-08 11:26:30",
  "createdByUser": 2,
  "createdByToken": null,
  "creationMethod": "Frontend",
  "updatedAt": "2026-05-08 13:31:35",
  "updatedByUser": 1,
  "updatedByToken": "Postman",
  "updateMethod": "API"
}
```

`creationMethod` and `updateMethod` are derived automatically — `"API"` when a token was used, `"Frontend"` when the action came through the UI.

---

<h3 style="color: #203671; margin-top: 2.2em;">Render-Specific Request Body</h3>

The render endpoint (`POST /api/v1/report-config/{id}/render`) accepts the following fields in the **request body** (JSON).

<table style="width: 100%; border-collapse: collapse;">
  <thead>
    <tr style="border-top: 1px solid #e6e8ef; border-bottom: 1px solid #e6e8ef;">
      <th style="text-align: left; padding: 6px 10px; white-space: nowrap;">Field</th>
      <th style="text-align: left; padding: 6px 10px;">Type</th>
      <th style="text-align: left; padding: 6px 10px;">Required</th>
      <th style="text-align: left; padding: 6px 10px;">Description</th>
    </tr>
  </thead>
  <tbody>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>outputType</code></td><td style="padding: 6px 10px;">string</td><td style="padding: 6px 10px;">✅</td><td style="padding: 6px 10px;">How to return the PDF: <code>base64</code>, <code>url</code>, <code>preview</code>, or <code>none</code></td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>createHistoryRecord</code></td><td style="padding: 6px 10px;">boolean</td><td style="padding: 6px 10px;">✅</td><td style="padding: 6px 10px;">Whether to persist a <code>ReportHistoryRecord</code> for this render</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>createPrintTask</code></td><td style="padding: 6px 10px;">boolean</td><td style="padding: 6px 10px;">✅</td><td style="padding: 6px 10px;">Whether to create a <code>ReportPrintTask</code> after rendering</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>printerName</code></td><td style="padding: 6px 10px;">string</td><td style="padding: 6px 10px;">if <code>createPrintTask</code></td><td style="padding: 6px 10px;">Name of the target printer</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>useExampleValues</code></td><td style="padding: 6px 10px;">boolean</td><td style="padding: 6px 10px;"></td><td style="padding: 6px 10px;">Use stored example values instead of supplying parameters manually</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>parameters</code></td><td style="padding: 6px 10px;">object</td><td style="padding: 6px 10px;"></td><td style="padding: 6px 10px;">Key-value map of parameter names to values</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>data</code></td><td style="padding: 6px 10px;">array</td><td style="padding: 6px 10px;"></td><td style="padding: 6px 10px;">Array of data rows — for reports without a live DB connection</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>numberOfCopies</code></td><td style="padding: 6px 10px;">integer</td><td style="padding: 6px 10px;"></td><td style="padding: 6px 10px;">Number of print copies (default: 1)</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>broadcastId</code></td><td style="padding: 6px 10px;">string</td><td style="padding: 6px 10px;"></td><td style="padding: 6px 10px;">WebSocket channel ID — triggers real-time status updates for the print task</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>traceId</code></td><td style="padding: 6px 10px;">string</td><td style="padding: 6px 10px;"></td><td style="padding: 6px 10px;">Custom trace ID; auto-generated as UUID if omitted</td></tr>
    <tr><td style="padding: 6px 10px; white-space: nowrap;"><code>laconicResponse</code></td><td style="padding: 6px 10px;">boolean</td><td style="padding: 6px 10px;"></td><td style="padding: 6px 10px;">Strip the response to just the PDF output (see below)</td></tr>
  </tbody>
</table>

<div style="border-left: 4px solid #203671; background: #f0f3fb; padding: 10px 16px; margin: 16px 0; border-radius: 0 4px 4px 0;">
⚠️ <strong>Output type <code>none</code> requires <code>createPrintTask: true</code>.</strong> Rendering without any output and without a print task is rejected.
</div>

<h4 style="color: #203671; margin-top: 1.4em;">Laconic Responses</h4>

By default, a render response is fully populated — it includes the echoed input, the PDF output, the linked `ReportConfig`, the created `ReportHistoryRecord`, and the `ReportPrintTask` if applicable. In high-frequency or bandwidth-sensitive scenarios, add `laconicResponse=true` to strip everything down to just the PDF output.

---

<h3 style="color: #203671; margin-top: 2.2em;">Rate Limiting</h3>

The API enforces a configurable rate limit per token. The default is **10 requests per minute**. When the limit is exceeded:

```json
{
  "success": false,
  "message": "Too many requests! The current rate limiting is 10 requests per minute.",
  "status": 429
}
```

The limit is adjusted via the `API_RATE_LIMIT_PER_MINUTE` environment variable — see [Configuration and Data Models](/books/veloxfactory/page/configuration-and-data-models).

---

<h3 style="color: #203671; margin-top: 2.2em;">Endpoints Overview</h3>

| Resource | Available operations |
|---|---|
| **User** | List, show, create, update, change password, enable/disable, create/revoke tokens |
| **ReportContext** | List, show, create, update, delete |
| **ReportConnectionConfig** | List, show, create, update, delete, test connection |
| **CommonReportResource** | List, show, create, update, delete |
| **ReportConfig** | List, show, create, update, delete, update resources / parameters / fields, generate previews, **render** |
| **ReportResource** | Link / unlink CommonReportResource |
| **ReportHistoryRecord** | List, show, create, update, delete, print |
| **ReportPrintTask** | List, show, create, update, delete, set printed, set status |

---

<h3 style="color: #203671; margin-top: 2.2em;">A Practical Example: The Full Render Response</h3>

A render call returns a `ReportRendering` object. By default it is fully populated — you see the input you sent, the PDF output, and the linked records that were created.

```json
{
  "success": true,
  "count": 1,
  "data": {
    "model": "ReportRendering",
    "traceId": "a3f9c1d2-4e87-4b2a-9f1c-d3e8b7a20f61",
    "input": {
      "parameters": {
        "P_ARTICLE_NUMBER": "4561287-154"
      },
      "data": null
    },
    "output": {
      "reportPdfFileName": "a3f9c1d2-4e87-4b2a-9f1c-d3e8b7a20f61.pdf",
      "reportPdfBase64": "JVBERi0xLjQ...",
      "reportUrl": null
    },
    "reportConfig": { "..." },
    "reportHistoryRecord": { "..." },
    "reportPrintTask": null
  },
  "meta": {
    "traceId": "a3f9c1d2-4e87-4b2a-9f1c-d3e8b7a20f61"
  },
  "status": 200
}
```

Add `laconicResponse=true` and the response collapses to just `output` — no echoed input, no embedded related records. Ideal for automated pipelines that only need the PDF.

</div>