Fabrixa Integration API Reference
6 min read Last updated: 10-06-2026 15:28
The Integration API helps you create and manage Fabrixa orders, launch Fabrixa Studio, and stay in sync with production and fulfilment status via webhooks. The API follows REST conventions and uses JSON for all request and response bodies.
BASE URL
https://api.fabrixa.com/v2/integration
Send all requests to this base URL followed by the specific endpoint path. The base URL is the foundation for interacting with the Fabrixa API - retrieving, creating, updating, or deleting resources.
Authentication
To access the Integration API, authenticate your requests using both an Application Access Token and an Application Key:
Authorization Header
Authorization: Bearer APPLICATION_ACCESS_TOKEN
Application Key Header
X-Application-Key: APPLICATION_KEY
Example cURL Command
curl -X 'GET' \
'https://api.fabrixa.com/v2/integration/ping' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer APPLICATION_ACCESS_TOKEN' \
-H 'X-Application-Key: APPLICATION_KEY'
Replace APPLICATION_ACCESS_TOKEN with your actual access token and APPLICATION_KEY with your actual application key.
Endpoints and Requests
The Integration API endpoints are organized by resource type and follow the RESTful architectural style. Each endpoint represents a resource, and actions on these resources are performed using standard HTTP methods.
All Integration API requests and responses are in JSON format, providing a consistent and easy-to-use interface for interacting with the API.
For full details on every endpoint, including request and response examples, see our Swagger documentation.
Response Format
All endpoints return data in a standardized format with these objects:
{
"links": {
"self": "https://api.fabrixa.com/v2/integration/products",
"first_page": "https://api.fabrixa.com/v2/integration/products?page=1",
"last_page": "https://api.fabrixa.com/v2/integration/products?page=2",
"next_page": "https://api.fabrixa.com/v2/integration/products?page=2",
"prev_page": null
},
"meta": {
"total": 2,
"current_page": 1,
"per_page": 10
},
"data": [
{
"id": 1,
"name": "Product 1",
"description": "Description of Product 1"
},
{
"id": 2,
"name": "Product 2",
"description": "Description of Product 2"
}
]
}
Description of Response Objects
links
Contains pagination links to navigate through the results.
self— the URL of the current page.first_page— the URL of the first page of results.last_page— the URL of the last page of results.next_page— the URL of the next page.nullif there is no next page.prev_page— the URL of the previous page.nullif there is no previous page.
meta
Contains metadata about the response, such as pagination information.
total— the total number of items available across all pages.current_page— the current page number of the results.per_page— the number of items per page.
data
The main content of the response. data varies by endpoint - it can be a single object, for example one product, or an array of objects, for example a list of products.
Errors and Status Codes
All API requests return HTTP status codes that provide insight into the response.
400 Bad Request
The server cannot process the request due to validation errors - missing or invalid parameters.
401 Unauthorized
The client has not provided valid authentication credentials. Also returned when the access token has been revoked.
403 Forbidden
The server denied the request due to insufficient access rights, typically caused by incorrect or missing access permissions.
404 Not Found
The requested resource could not be found on the server.
429 Too Many Requests
The client has exceeded the allowable number of requests in a given timeframe. See Rate Limits.
5xx Errors
An internal server error occurred. Please contact Fabrixa support with details of the failed request.
Error Response Body
An example of an error response body:
{
"links": {
"self": "https://api.fabrixa.com/v2/integration/ping"
},
"meta": [],
"errors": {
"messages": [
"Application Key is not specified."
]
}
}
errors contains details about what failed. The messages array lists error descriptions. For a Bad Request, you will receive the names of the fields that failed validation.
Rate Limits
The Integration API supports a limit of 30 requests per application per minute.
If you exceed this limit you will receive a 429 Too Many Requests response.
All Integration API responses include the X-RateLimit-Remaining header, how many requests the client can still make, and the X-RateLimit-Limit header, the total allowed per minute.
Orders
Create orders in Fabrixa from your own storefront or platform, attach the required print files, and follow each item as it moves through fulfilment.
Create an Order
To create an order via the Fabrixa Integration API, send a POST request to https://api.fabrixa.com/v2/integration/orders. The request body must include:
Request Body Structure
number(optional) - the order number. If not provided, a unique number is generated.comments(optional) - any additional comments or notes related to the order.purchased_at- date and time when the order was purchased, formatted asYYYY-MM-DD HH:MM:SS.client_ip(optional) - the IP address of the customer.client_user_agent(optional) - the user-agent string of the customer.rows- array of order items, each containing:sku- the SKU of the product variant. See Swagger for details.quantity- quantity of the product variant ordered.client_barcode(optional) - unique client-side identifier per order line, formatted asCode 128.cart_item_key(required withoutsources) - unique identifier from the platform embedding Fabrixa Studio, used to associate saved customizations with the order.sources(required withoutcart_item_key) - array of source files associated with the product, each containing:type- the product type, use"file"by default.url- URL of the source file.
customer- customer details:first_name,last_name,email,phone.
shipping_address- shipping details:address,address2(optional),address3(optional).city,country_code(ISO 3166-2),country,postal_code,state(optional).first_name,last_name,phone(optional),company(optional).
shipping_label(optional) - label details:method_name- e.g. "Post NL".tracking_number,tracking_url,label_pdf_url.date_created- formatted asYYYY-MM-DD HH:MM:SS.
Sample Request
{
"number": "NL2024010201",
"comments": "Customer agrees with a low resolution file.",
"purchased_at": "2024-06-26 21:12:22",
"client_ip": "127.0.0.1",
"client_user_agent": "Mozilla",
"rows": [
{
"variant_id": 2705,
"quantity": 1,
"client_barcode": "1234567890",
"sources": [
{
"type": "file",
"url": "https://samples-files.com/samples/sample.pdf"
}
]
}
],
"customer": {
"first_name": "John",
"last_name": "Doe",
"email": "3VJtP@example.com",
"phone": "0647185332"
},
"shipping_address": {
"address": "Pierre cuypershof",
"address2": "17",
"city": "Amsterdam",
"country_code": "NL",
"country": "Netherlands",
"postal_code": "1012 AB",
"state": "North Holland",
"first_name": "John",
"last_name": "Doe",
"phone": "0647185332"
},
"shipping_label": {
"method_name": "Post NL",
"tracking_number": "3SYZXG1585577",
"tracking_url": "https://postnl.nl/tracktrace/3SYZXG1585577",
"label_pdf_url": "https://api.fabrixa.com/storage/8966630826422f36d822f91680012141.pdf",
"date_created": "2024-01-01 00:00:00"
}
}
Track Fulfillment
To get the fulfilment status for a specific order, send a GET request to https://api.fabrixa.com/v2/integration/orders/{order_id}/fulfillments. The response provides a list of fulfilments associated with the order, including each item status, product details, and production-step progress.
Sample Response
{
"data": [
{
"id": 1499,
"barcode": "1200004169200",
"status": "unfulfilled",
"created_at": "2024-08-19T12:38:59.000000Z",
"updated_at": "2024-08-19T12:39:00.000000Z",
"variant": {
"id": 32327,
"name": "Test iAPI blanket product",
"subtitle": "100 x 150 cm",
"SKU": "COF099191"
},
"product": {
"id": 1306,
"name": "Test iAPI blanket product",
"subtitle": "Test iAPI blanket product"
},
"production_steps": [
{
"id": 5,
"name": "Print duvet",
"description": "Printing the duvet according to the specified design and dimensions.",
"status": {
"value": "pending",
"notes": null,
"updated_at": null
}
},
{
"id": 6,
"name": "Print pillow",
"description": "Printing the pillow cover with the assigned design.",
"status": {
"value": "pending",
"notes": null,
"updated_at": null
}
}
]
}
]
}
The response includes a list of fulfilments, each providing:
id- unique identifier for the fulfilment.barcode- barcode for internal tracking and identification; can also be printed on the product.status- the current fulfilment status: unfulfilled or fulfilled.created_atandupdated_at- timestamps for fulfilment creation and last update.variant- detailed information about the product variant: name, subtitle, SKU.product- product details: name, subtitle.production_steps- array of production steps. The list of steps depends on the product type. For each step:id- unique identifier for the production step.name- e.g. "Print duvet".description- what the production step entails.status- the current status:- pending - not yet started.
- in progress - currently underway.
- rejected - the step encountered an issue and was not completed successfully.
- done - the step has been completed.
notes- any additional notes related to the step.updated_at- the last time the step status was updated.
Each fulfilment record corresponds to a specific product or product variant within the order, and each copy of the product in the order has its own fulfilment record - every item is tracked individually throughout production.
If no fulfilments are returned for an order, the order has not yet entered the processing stage.
Source File Requirements
When including source files in your order, ensure they meet the following requirements:
type
You must provide a PDF file as the source. If your design contains multiple product layers, include each layer as a separate page in the same PDF. During processing, each page is treated as an individual layer, allowing you to submit a multi-layer design as a single source file. See PDF requirements and page order.
The type in the source object must be set to "file".
"sources": [
{
"type": "file",
"url": "https://samples-files.com/samples/source.pdf"
}
]
For further details, see the Swagger documentation.
url
The url field must contain a direct link to the source file. Ensure the URL is accessible and the file can be downloaded without authentication. The link must remain accessible throughout the production process.
File Format
Provide files in PDF format. Ensure images are high-quality and suitable for printing.
Image Dimensions
Maximum dimensions are 15,000 pixels on either side. Images exceeding this limit may be resized or rejected. Image resolution should match product dimensions; otherwise images may be resized or cropped to fit.
Resolution
No specific resolution requirement - just ensure image quality is sufficient for printing.
Color Space
Images should be in RGB color space for accurate colour representation. Other colour spaces will be converted during processing, which may result in incorrect colours.
File Size
Each source file should not exceed 50 MB. Larger files may be rejected or cause processing delays.
PDF Requirements and Page Order
The order of pages in the PDF is important. Pages are matched to product layers by position, and the expected page order depends on the product type. Make sure the pages in your PDF follow the correct layer sequence for the product you are submitting.
| Product | PDF page order |
|---|---|
| Duvet Cover |
|
| Curtains |
|
| T-shirt |
|
| Tanktop |
|
| Sweater |
|
| Hoodie |
|
| Sweatpants |
|
| Sweatshorts |
|
Important: each PDF page must match the required dimensions for its product layer and be oriented correctly. Place the artwork so the top of the design aligns with the top of the page. Incorrect page size or orientation may cause scaling, rotation, or alignment issues in production.
Fabrixa Studio
Fabrixa Studio is a tool that lets users seamlessly customize and personalize products in real time with an intuitive interface where users can create or upload their own designs.
Fabrixa Studio is ideal for businesses offering custom products - enabling customers to visualize their designs before finalizing orders.
Embed Fabrixa Studio
You can embed Fabrixa Studio into your website using an iframe. This enables your customers to personalize products directly on your site during checkout.
Example iframe for embedding Fabrixa Studio:
<iframe id="fabrixa-studio"
src="https://studio.fabrixa.com?application_key={application_key}&sku={product_sku}&cart_item_key={cart_item_key}"
name="FabrixaStudio"
scrolling="no"
frameborder="1"
width="100%"
height="100%"
allowfullscreen="">
</iframe>
Replace the values for product_sku, cart_item_key, and application_key with your dynamic values.
application_key- unique key for authenticating to the Integration API.product_sku- the SKU of the product variant, retrieved from the Integration API.cart_item_key- a unique value from the embedding platform identifying the cart item associated with the product. Used to save the user customizations; during order creation it identifies the saved customizations and assigns them to the order. See example below.
Request to Create an Order with cart_item_key
{
"number": "NL2024010201",
"purchased_at": "2024-06-26 21:12:22",
"client_ip": "127.0.0.1",
"client_user_agent": "Mozilla",
"rows": [
{
"sku": "SB796162",
"quantity": 1,
"cart_item_key": "0cb76770-de2d-4524-aa48-47b6e5f0d8a5"
}
],
"customer": {
"...": "..."
},
"shipping_address": {
"...": "..."
},
"shipping_label": {
"...": "..."
}
}
Handle Studio Events
When the Add to Cart button is clicked inside the iframe, the following command is executed:
window.parent.postMessage('customizationFinished', '*');
Similarly, when the Back button is clicked:
window.parent.postMessage('closeButtonClicked', '*');
The postMessage method facilitates cross-origin communication between the iframe and its parent window, allowing it to notify the parent about specific user actions.
The first argument of postMessage is the data you want to send. The string 'customizationFinished' indicates the user has finalized customization and is adding the product to the cart. 'closeButtonClicked' indicates the user has chosen to go back.
In the parent window, listen for these messages using the message event listener:
window.addEventListener('message', function(event) {
if (event.origin === 'https://studio.fabrixa.com') {
if (event.data === 'customizationFinished') {
// Handle the Add to Cart event
console.log('Customization finished and item can be added to cart.');
} else if (event.data === 'closeButtonClicked') {
// Handle the Back button event
console.log('Back button clicked.');
}
}
});
Always check the origin of incoming messages to ensure they come from a trusted source. Depending on the message received, perform the necessary actions - update the user interface, process the cart, etc. Validating origin is crucial for security - it prevents unauthorized scripts from interacting with your application.
Customization Preview
After customization is completed, display the final design using the preview URL below. This URL returns an image of the customized product, suitable as the src value in an <img> tag. Ideal for showing the customized product in your cart, order summary, or anywhere in your shop interface.
https://api.fabrixa.com/v2/studio/customizations/{CART_ITEM_KEY}/preview?Application-Key={APPLICATION_KEY}
Replace {CART_ITEM_KEY} with the actual cart item key and {APPLICATION_KEY} with your valid application key.
Example usage in an image tag:
<img
src="https://api.fabrixa.com/v2/studio/customizations/{CART_ITEM_KEY}/preview?Application-Key={APPLICATION_KEY}"
alt="Customized Product Preview"
style="max-width: 100%; height: auto;" />
Live Demo
The customization preview will appear here after the design is finished.
Webhooks
Webhooks are used by Fabrixa to notify your system about real-time events - order updates or creations. When an event occurs, Fabrixa sends a webhook to your server containing the relevant information. Your server must expose a public POST endpoint to handle incoming webhooks.
Webhook Request Headers
The webhook request includes the following headers to help you identify and validate the incoming request:
{
"content-type": "application/json",
"x-webhook-signature": "YmEwNjBhMGMyMzE3ZWQ5NGQ5NDYwOGVhNzNhMjQ4M2MyODZkZmI3NTQ1YzYxYjdkMzNhZjgzYzBmMTkxYTAxMw==",
"x-webhook-topic": "order.updated"
}
Header Breakdown
content-type- always set toapplication/jsonfor webhooks.x-webhook-signature- the HMAC-SHA256 signature for request verification.x-webhook-topic- the event type or topic of the webhook. For example:order.created- triggered when a new order is created.order.updated- triggered when an existing order is updated.
Webhook Events
Fabrixa webhooks notify your system of changes in order status or activity. Each webhook is triggered by a specific x-webhook-topic value. Currently supported topics:
| Topic | Description |
|---|---|
order.created |
Triggered when a new order is placed in Fabrixa, either via API request or directly in the platform. |
order.updated |
Triggered when order details such as the order status or fulfilment status are updated. |
Order Statuses
- Completed - order has been shipped or picked up, and receipt is confirmed. For digital products, the client has paid and files are available for download.
- Canceled - customer canceled payment; the transaction was not completed.
- On hold - the order is temporarily blocked.
- Imported - the order was imported into the platform.
Fulfillment Statuses
- Unfulfilled - the order has not been prepared or sent out yet.
- Partially fulfilled - some items have been processed or shipped, others still pending.
- Scheduled - order is planned and scheduled for processing.
- Rejected - the fulfilment request has been declined, often due to invalid order details or unavailability.
- Fulfilled - the order has been completely processed and delivered or made available to the customer.
Webhook Payload Example
An example of the payload sent with the webhook. This payload represents an order update:
{
"id": 23069,
"number": "1250211835",
"comments": null,
"is_archived": false,
"status": "imported",
"fulfillment_status": "unfulfilled",
"purchased_at": "2025-04-17T16:17:21.000000Z",
"created_at": "2025-04-17T16:17:23.000000Z",
"updated_at": "2025-04-18T07:43:52.000000Z",
"rows": [
{
"id": 27954,
"quantity": 1,
"client_barcode": "1250211835",
"fulfillment_status": "unfulfilled",
"variant": {
"id": 293457,
"name": "Sherpa fleece deken",
"subtitle": "100x150",
"SKU": "SFD787231",
"product": {
"id": 5319,
"name": "Sherpa fleece deken",
"subtitle": "Sherpa fleece deken"
}
},
"sources": [
{
"type": "print",
"url": "https://storage.googleapis.com/fabrixa-api/storage/99b10aaa-df4d-47e4-9bc9-b1d6a785df4c/orders/merchandise-sources/120002795400.pdf",
"properties": {
"fill_style": "contain"
}
}
]
}
]
}
Verify Webhook Signatures
To ensure the webhook request is authentic and untampered, verify the x-webhook-signature header. This involves recalculating the HMAC-SHA256 signature using the raw request payload and your secret key, then comparing it to the received signature.
Raw PHP Example
$payload = file_get_contents('php://input');
$yourSecret = 'your-secret-key';
$expectedSignature = base64_encode(hash_hmac('sha256', $payload, $yourSecret, true));
$receivedSignature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
if (!hash_equals($expectedSignature, $receivedSignature)) {
http_response_code(403);
exit('Invalid signature');
}
Laravel Example
public function handle(Request $request)
{
$yourSecret = 'your-secret-key';
$payload = $request->getContent();
$expectedSignature = base64_encode(hash_hmac('sha256', $payload, $yourSecret, true));
$receivedSignature = $request->header('x-webhook-signature');
if (!hash_equals($expectedSignature, $receivedSignature)) {
abort(403, 'Invalid signature');
}
// Continue processing...
}
Replace $yourSecret with your shared secret key. Always use hash_equals for comparing signatures to mitigate timing attacks.
Webhook Retries
Webhooks are disabled after 10 unsuccessful delivery attempts by default. If your endpoint returns an unsuccessful status such as 404 or any 5xx error, the webhook will retry for a total of 10 times. If it continues to return a non-2xx or non-3xx response code, it will be deactivated. Successful responses include:
2xx- indicates successful processing, e.g.200 OK.301and302- redirection responses indicating the webhook has been successfully handled or forwarded.
Webhook Response
We strongly recommend your endpoint returns a 200 OK status code as quickly as possible to acknowledge successful receipt of the webhook. While any 2xx or 3xx response is considered successful, 200 is the most commonly used and reliable.
To avoid delivery timeouts or retries, return 200 OK immediately and handle webhook payload processing asynchronously, for example via a background job or queue. If your endpoint takes too long to respond, it may be considered a failure even if the response is ultimately successful.
Responses with status codes in the 4xx or 5xx range, or timeouts, will trigger retries according to the retry mechanism.