Skip to main content

Status Information

This guide explains the different status types in the Shirtigo Cockpit system, including order statuses and individual product item statuses.

Table of Contents​

Order Status Keys​

The following table shows all possible order status values:

Status KeyDescription
pendingOrder created and payment pending
openPayment successful
successfulProduction preparation
productionIn production
shippedShipped
clarificationClarification needed
out-of-stockSupply shortage
documents-requiredCommercial invoice required
processing-failedOrder was cancelled due to failed async image processing
payment-failedPayment failed
refundOrder cancelled

Handling Failed Status Cases​

When an order enters a failed status, specific actions are required to resolve the issue:

Clarification Status​

If the order status is clarification, use the Update delivery address endpoint, PUT /orders/{order_reference}, to submit a corrected delivery address.

The body differs from the delivery object used when placing an order. It is a flat address object and requires the id of the address to update:

{
"address": {
"id": 123456,
"street": "Musterstraße 12",
"postcode": "12345",
"city": "KΓΆln"
}
}

The id is returned by GET /orders/{order_reference} as the address with type delivery. Besides id, the endpoint accepts company, firstname, lastname, care_of, street, postcode and city. The country of an existing order cannot be changed.

Note: Without id the address is silently ignored and the endpoint still answers 204. This is the most common cause of "the update did nothing".

The corrected address is validated before it is stored, so a still incomplete correction is rejected with 400 and the response body names the failing fields. Once it validates, the clarification is resolved, the order returns to its regular status and an Order.updated webhook is sent.

Documents Required Status​

If the order status is documents-required, use the Upload Merchant Invoice endpoint to submit a customs invoice. You can either add the merchant-invoice with the initial POST /orders call by adding a document to the request. The document needs to be uploaded upfront by using the Upload Order Document endpoint.

Processing Failed Status​

If the order status is processing-failed, check the error in the related design objects and submit the order again with corrected files.

Payment Failed Status​

If the order status is payment-failed, this typically occurs due to insufficient credit card funds. You can use the Retry payment endpoint to attempt the payment again.

Important: API orders can only be placed with the following payment methods:

  • Prepayment
  • Direct debit (requires key account activation)
  • Wallet

Order Product Item Status Keys​

The following table shows all possible status values for individual order product items that can be received through webhooks:

Status KeyStatus GroupDescription
pendingpreparingItem was pushed to production system
orderedpreparingPick order for item was created
printedprocessingPick label for item printed and item picked
pretreatmentprocessingProduct is being pretreated
embroideryprocessingProduct is in embroidery process
dtgprocessingProduct is being printed
additionalprocessingAdditional processing step is performed
brandingprocessingProduct is being branded
passedprocessingProduct passed quality control
refusedfailedProduct failed quality control and will be reproduced with new item
sortingsuccessfulProduct is in outbound sorting
readysuccessfulProduct ready for shipping
shippedsuccessfulProduct has been shipped
cancelledfailedProduct has been cancelled

Note: The status progression typically follows the order: preparing β†’ processing β†’ successful/failed. Each product item in an order can have its own status, allowing for detailed tracking of individual items. If a item fails a new one will be created for the same orderProduct.


Webhooks

Webhooks provide a way to receive real-time updates for specific events in your Shirtigo Cockpit. This section explains how to register webhooks, available events, and how to verify webhook authenticity.

How to Choose a URL for Your Webhook​

To use a webhook, you need to define a publicly accessible URL in your system where webhook requests will be sent. The URL should be able to:

  • Accept POST requests.
  • Process the incoming JSON payload correctly.
  • Respond with a 2xx HTTP status code to confirm successful receipt.

Note: If authentication is required, ensure that the webhook URL can still receive requests without restrictions, as this may interfere with delivery.

Available Webhook Events​

Webhooks are triggered by specific events, which are defined by:

  • Key: A unique identifier that combines the resource and action.
  • Resource: The entity being affected (e.g., Order, Product, Design).
  • Action: The type of event occurring (e.g., Created, Updated, Deleted).

Supported Webhook Events​

Keys are case-sensitive. The authoritative list is always available via GET /webhook-types.

KeyResourceActionDescription
Order.createdOrdercreatedTriggered when a new order is placed.
Order.creation-failedOrdercreation-failedTriggered when an order cannot be created due to an issue (e.g., print file errors).
Order.updatedOrderupdatedTriggered when an order status changes.
Order.shippedOrdershippedTriggered when an order is shipped.
Order.clarificationOrderclarificationTriggered when an order needs your input. Covers an invalid delivery address (clarification), a supply shortage (out-of-stock) and a missing customs invoice (documents-required); see below.
Order.canceledOrdercanceledTriggered when an order is canceled.
OrderProductItem.updatedOrderProductItemupdatedTriggered when an individual product item's status changes.
Product.createdProductcreatedTriggered when a new product is created.
Product.updatedProductupdatedTriggered when a product is updated.
Product.deletedProductdeletedTriggered when a product is deleted.
Design.createdDesigncreatedTriggered when a design is created.
Design.rendering-failedDesignrendering-failedTriggered when design rendering fails.
Design.updatedDesignupdatedTriggered when a design is updated.
Design.deletedDesigndeletedTriggered when a design is deleted.
GeneratedMedia.renderedGeneratedMediarenderedTriggered when a rendering-task for the Mockup-Factory is completed.
OrderWarehouseProductItem.updatedOrderWarehouseProductItemupdatedTriggered when an individual warehouse product item's status changes.
UserInboundShipping.createdUserInboundShippingcreatedTriggered when a return for an order arives.

How to Register a Webhook URL​

To register a webhook, send a POST request to the /webhooks endpoint with the following parameters:

Webhook Parameters​

ParameterTypeRequiredDescription
resourcestringRequired without typesThe entity the webhook listens to (e.g., "Order", "Product"). Must be combined with action.
actionstringRequired without typesThe event type (e.g., "created", "updated"). Must be combined with resource.
typesarrayRequired without resource and actionAn array of webhook event keys (e.g., ["Order.created", "Product.updated"]).
urlstringYesThe endpoint where the webhook request will be sent.
secretstringNoA secret key for verifying request signatures.
signature_headerstringNoDefines the header field used for webhook signatures (default: signature).
is_activebooleanNoSpecifies whether the webhook is active (true) or not (false).

Example: Register a Webhook for New Orders​

{
"resource": "Order",
"action": "created",
"url": "https://yourserver.com/api/webhook-listener"
}

This webhook will send a POST request to https://yourserver.com/api/webhook-listener whenever a new order is created.

The Order.clarification Payload​

One event key covers three situations, so the payload carries extra fields under extra_data to tell them apart:

FieldWhenDescription
clarification_typealwaysThe order status key: clarification, out-of-stock or documents-required.
address_errorsclarificationThe individual objections against the delivery address.
address_validation_errorsclarificationThe parsed carrier preflight response, where one is available.
order_product_referencesout-of-stockReferences of the order products that are unavailable.

This is the event to listen to when you place orders with delayed_address_validation, because an address that fails validation puts the order into clarification instead of rejecting it at creation time.

Receiving Webhooks​

When is a Webhook Considered Successfully Delivered?​

A webhook is successfully delivered when your server responds with an HTTP 2xx status code (e.g., 200 OK, 204 No Content).

If your server does not respond with a 2xx status, Shirtigo will retry sending the webhook.

How Are Failed Webhook Deliveries Handled?​

Webhook retries follow an exponential backoff strategy. The waiting time doubles after each failed attempt, so a delivery is attempted five times in total:

AttemptSent after
1immediately
2~15 minutes
3~30 minutes
4~60 minutes
5~120 minutes

After the fifth failed attempt the webhook is disabled (is_active becomes false) and no further attempts are made, neither for this event nor for any later one. You then have to reactivate it via PUT /webhooks/{id}.

Tip: Keep this in mind while developing. An endpoint that answers with 500 during testing will have its webhook switched off after the fifth failure.

Tip: Ensure your webhook handler responds quickly and always returns a 200 OK status.

How to Verify That a Webhook is Sent by Shirtigo Cockpit​

Each webhook request includes a cryptographic signature that allows you to verify its authenticity. This signature is calculated using the HMAC SHA-256 algorithm with your webhook's secret key.

When you register a webhook, you can provide:

  • A secret parameter (a random string known only to you and Shirtigo). If you omit it, one is generated for you and returned in the response.
  • A custom signature_header parameter (defaults to signature if not specified)

For each webhook request, Shirtigo:

  1. Takes the JSON payload as a string
  2. Creates an HMAC SHA-256 hash using your secret
  3. Sends this signature in the request header you specified

Signature Format​

  • The signature is a lowercase hexadecimal string of 64 characters.
  • It is not base64 encoded and carries no prefix such as sha256=.
  • It is calculated over the raw request body, byte for byte as transmitted.

Important: Verify the signature against the raw body, not against a re-serialized object. Parsing the JSON and serializing it again changes key order, spacing and escaping, which produces a different hash and makes every request look invalid.

Important: Retries send a modified body. Each retry carries a new webhook_call_id, a new created_at and an additional parent_call_id. The signature belongs to the body of that individual request, so recompute it per request rather than caching it.

Example: Verifying Webhook Signature (PHP)​

function verifyWebhookSignature($payload, $receivedSignature, $secret) {
// Calculate expected signature using HMAC SHA-256
$expectedSignature = hash_hmac('sha256', $payload, $secret);

// Use timing-safe comparison
return hash_equals($expectedSignature, $receivedSignature);
}

// In your webhook handler:
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_SIGNATURE']; // Or your custom header
$secret = 'your_webhook_secret';

if (verifyWebhookSignature($payload, $signature, $secret)) {
// Process valid webhook
http_response_code(200);
} else {
// Reject invalid request
http_response_code(401);
}

Example: Verifying Webhook Signature (Node.js)​

const crypto = require('crypto');

// rawBody must be the untouched request body (Buffer or string), NOT a parsed object.
function verifySignature(rawBody, signature, secret) {
const expected = crypto.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');

const a = Buffer.from(expected, 'utf8');
const b = Buffer.from(String(signature || ''), 'utf8');

// timingSafeEqual throws on differing lengths, so check that first
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

If you use Express, note that express.json() discards the raw body. Keep it around:

app.use(express.json({
verify: (req, res, buf) => { req.rawBody = buf; }
}));

app.post('/webhook-listener', (req, res) => {
if (!verifySignature(req.rawBody, req.get('signature'), process.env.WEBHOOK_SECRET)) {
return res.sendStatus(401);
}
// process req.body
res.sendStatus(200);
});

Security Tips:

  • Use a strong, random string as your webhook secret
  • Store your secret securely (e.g., in environment variables)
  • Always verify the signature before processing webhook data
  • Use a timing-safe comparison to prevent timing attacks

How to Test a Webhook​

You can test webhooks before integrating them into production.

1. Using the Test Endpoint​

Send a POST request to /webhooks/{id}/test with a valid resource_id:

{
"resource_id": "CXY563"
}

This simulates a real event, but the payload will contain "mode": "test".

2. Using a Webhook Testing Service​

Use tools like Webhook.site to inspect real-time webhook requests.

3. Using cURL for Manual Testing​

curl -X POST https://yourserver.com/webhook-endpoint \
-H "Content-Type: application/json" \
-d '{"type":"Order.created","resource":{"reference":"123456"}}'

Conclusion​

This documentation covers both the status information available in the Shirtigo Cockpit system and how to use webhooks to receive real-time updates. By understanding the various status types and properly configuring webhooks, you can effectively track orders and automate your workflows.