Webhooks
To avoid the need for polling, RPI Print API sends webhooks, which are HTTP notifications, when
certain order events happen. To turn them on, set the webhookUrl property when you create an order.
RPI Print API retries a webhook for about 7.5 hours: five times about 30 seconds apart, then about every 15 minutes. Delivery is not guaranteed.
If your integration can miss a webhook, call GET /orders/{customerOrderId} to recover the order's current status.
Every webhook body is JSON that describes the order, much like the response to a GET request for it.
Set webhookUrl in the create order request:
{
"webhookUrl": "https://endpoint.com/callbacks/741231"
}
Each order can have a different webhookUrl, and the URL may include query parameters, for example
?orderid=1234. During development you might want to use a webhook testing service, such as
https://webhook.site or https://ngrok.com/.
The create request fails if webhookUrl does not meet these requirements:
- It must be a valid URL of no more than 2048 characters.
- It must start with
https://. RPI Print API accepts no other protocol. - Its host must not be
localhostor an IP address in a private or reserved range, such as 192.168.x.x or 10.x.x.x.
Create does not check that the URL is reachable. For RPI Print API to deliver webhooks, the URL must be reachable from the public internet, and it should be an endpoint you control.
Webhook request
The webhook request sent to your endpoint has a JSON body with this structure:
| property name | type | description |
|---|---|---|
source | string | The event type that caused RPI Print API to send this webhook. |
time | string | The time of the event, in UTC, in ISO-8601 format. |
data | object | The order, as an OrderFullResponse described in the API reference. |
If an order cannot be created, the create request returns the error and RPI Print API sends no webhook.
List of webhook sources
source | event that causes this webhook |
|---|---|
OrderAcceptedByPrinter | The printer has confirmed that it received the order, and the order moves to RECEIVED_BY_PRINTER. The printer can refuse a cancellation request from PRINTING onward, which comes before this. |
OrderAssetsAllProcessed | Every file in the order has been processed successfully. |
OrderCancellationRequestSentToPrinter | The order is already at the printer, and RPI Print API has sent the printer a cancellation request. The printer will confirm or refuse it. |
OrderCancelledBeforeSubmissionToPrinter | The order was cancelled in the holding bin, before it was sent to the printer. |
OrderCancelled | The order was cancelled before it entered the holding bin, or the printer confirmed a cancellation request. A cancellation in the holding bin sends OrderCancelledBeforeSubmissionToPrinter instead. |
OrderCreated | The order has passed initial validation and is queued for further processing. |
OrderEnteredHoldingBin | The order has entered the holding bin, where it stays for about 2 hours. A cancellation during this time always succeeds. |
OrderErrorAtPrinter | The printer reported a problem printing the order. Check the order's details for more information, or contact customer support. |
OrderExceedsLimitQueue | The order arrived when both the daily order limit and the queue for orders over the limit were full, so it was rejected. RPI will not process it. |
OrderExitedHoldingBin | The order has left the holding bin, after 2 hours or when customer support released it early, and is scheduled to be sent to the printer. |
OrderExitedLimitQueue | An order that was over the daily order limit has been released from the queue and continues through the normal workflow. |
OrderFailed | Processing the order's files failed, which usually means there is a problem with the files. Check the order's validations for details. |
OrderFinishedPricing | RPI has applied pricing and taxes to the order, and those fields are now available. |
OrderInExceptionState | The order has entered the EXCEPTION state, which usually needs customer support to resolve. |
OrderInProduction | The printer has begun producing the order. |
OrderOverLimitQueued | The order has been placed in the queue for orders over the limit, because more than the maximum number of orders were submitted in the last 24 hours. |
OrderPricingReceived | For an order the printer prices, the printer has priced its items, and the pricing block now carries itemsTotal. RPI records this event once per order. |
OrderReadyToShip | The printer has produced the order, and it is ready to ship. |
OrderReceived | The order has passed initial validation, and RPI Print API has received it. |
OrderReprintRequested | A reprint of this order has been created. |
OrderShipped | The order has shipped. An order can ship in one shipment or several, and the last shipment ends the order's workflow. |
OrderShippingEstimatesRefreshed | RPI updated the order's shipping estimates before sending it to the printer. The ship date may have changed because of the time the order spent in the limit queue or the holding bin. |
OrderSubmittedToPrinter | The order has been sent to the printer and is waiting for the printer to confirm it. |
OrderValidationFailed | Validation of the order failed. Check the order's validations for details. |
OrderVoidedByPrinter | The printer has cancelled an order that had already reached it. |
PaymentFailure | A payment failed. RPI retries scheduled payments the next day. Check your payment information. |
PaymentSuccessful | A payment succeeded, and the orders waiting for it move to the holding bin. |
RefundSuccessful | A refund for this order has been processed. |
Webhook response
Your endpoint should respond with an HTTP status from 200 to 299, ideally within 10 seconds. If it does not, RPI Print API sends the webhook again later. After a number of failed attempts, RPI Print API stops sending that webhook.
The Event Logs tab on an order's page in the RPI Print API Dashboard lists each event on the order and when it happened. It does not show webhook bodies, delivery attempts, or failures.
Webhook signature
RPI Print API signs each webhook body with an hmac-sha256 signature, so that you can confirm that
RPI Print API sent the webhook and that nobody changed it on the way. The signature is a Base64
encoded hash, sent in the x-rpi-printapi-hmac-sha256 request header.
RPI Print API computes the signature with your webhook secret. The webhook secret is an authentication credential: anyone who has it can sign a request that your endpoint will accept as coming from RPI Print API. Store it as securely as your API keys.
Each customer has two webhook secrets, one for production and one for sandbox. Webhooks for production orders are signed with the production secret, and webhooks for sandbox orders with the sandbox secret. The API Keys page under Developer Tools in the dashboard shows the secret for the mode the dashboard is in.
Example: calculate hmac-sha256 in Node.js
import { createHmac } from "crypto"
...
const hmacSignature = createHmac('sha256', webHookSecret).update(webhookReceivedBodyAsString, 'utf8').digest('base64');
Polling for order status
If you do not use webhooks, you can poll for an order's status by calling
GET /orders/{customerOrderId}, which the API reference describes.
Order states describes each status it can return. Polling returns the same data
that a webhook delivers.
Polling suits displaying progress to your end user. For everything else, webhooks are easier to use and more reliable. If you need both to display progress and to continue a process in your backend, set up a webhook for the backend and poll only to display progress.