External Shipping Engine Draft
This document is a draft and what it contains is not available yet in any environment, and is subject to change.
This API integrates an external shipping service into Centra via a single-endpoint webhook system.
High Level Flow
Session started
Actions outside of checkout
Actions inside of checkout
Example checkout flow
Configuring/Installing the Integration
This has yet to be decided. In the MVP, this will likely require manual configuration by the Centra team.
Available Configuration Options
Some options will be available to configure.
| Option | Description |
|---|---|
| API URL | Endpoint the API will talk to. |
| Signing secret | Shared secret used for signing. |
| Markets | Which Markets this ESE serves. |
| Ship-to countries | Which destination countries this ESE serves. |
| Mode | Replace or Augment. Replace: ESE options replace Centra's built-in shipping. Augment: ESE options are shown alongside built-in shipping options. |
Attribute configuration
More detailed information to come, currently lists some expectations.
The integration will support defining multiple types of attributes. For products, these can provide shipping-related information not already available in the Centra product model. Order and shipment attributes let you decide which data should be persisted on a Centra order for use by other integrated systems.
Request Structure
Centra sends all requests as HTTP POST to your configured endpoint URL.
Request Signature
Centra signs every request using HMAC-SHA512. The signature is computed over the JSON-encoded request body using the shared signing secret configured in the plugin settings.
signature = HMAC-SHA512(JSON-encoded-request-body, signing-secret)
The signature is sent in the X-Request-Signature header. Your endpoint MUST verify this signature to authenticate requests from Centra. If verification fails, return a HTTP 401 Unauthorized response and do not process the request.
Request Payload Fields
Request payload is a JSON object.
| Field | Required | Type | Description |
|---|---|---|---|
| requestType | Y | string | The type of request. |
| requestContext | N | string | Additional context information per requestType |
| data | Y | object | The request data; structure varies based on requestType |
Versioning
The X-Api-Version header carries an integer that increments on breaking changes to the contract. The current version is 1.
A new major version means something has changed that requires your implementation to be updated — a field has been removed, renamed, or its semantics have changed in a non-backwards-compatible way.
Minor additions such as new optional request fields or new optional response fields will be made without incrementing the version. Your implementation should handle these gracefully by ignoring unknown fields, which is also required by the response validation rules.
Request Types
All requests are sent to your configured endpoint URL. The requestType field in the request body determines which operation is being performed:
| Request Type | Must Implement | Timeout | Description |
|---|---|---|---|
| shippingOptions | Y | varies — see Request Context | Calculate and return shipping options for a selection |
| optionLocations | N | 5 s | Return a list of pickup locations near a given address |
| orderCreated | Y | 10 s | Selection using a shipping option from this integration was completed and is now an order to be shipped. |
| testConnection | Y | 5 s | Verify the endpoint is reachable and credentials are valid |
Request Headers
Every request includes these headers:
| Header | Description |
|---|---|
| Content-Type | application/json |
| X-Client-Id | Centra client instance identifier |
| X-Request-Id | Unique identifier for this HTTP request. Always distinct across every call. |
| X-Correlation-Id | Centra's trace identifier for the logical operation that triggered this request. May be shared across requests belonging to the same operation. You should log this value — Centra uses it as the primary key when correlating your logs with internal logs during debugging. |
| X-Api-Version | API contract version integer. See versioning. |
| X-Request-Signature | HMAC-SHA512 signature of the request body. |
| User-Agent | Centra version information |
Response Headers
Your endpoint may optionally return the following headers in any response:
| Header | Description |
|---|---|
| X-Provider-Trace-Id | A trace identifier from your system. If present, Centra will include this value in all internal logs produced after receiving the response, making it easier to correlate Centra-side logs with your own. |
Response Validation
The following rules apply to all HTTP 200 responses, across all request types.
| Violation | Behaviour |
|---|---|
| Unknown/extra fields | Silently ignored. Extra fields will never cause a failure — this is a forward-compatibility guarantee. |
| String exceeds max length | Silently truncated to the limit (Unicode characters). Warning written to internal logs. |
| Array exceeds max size | First N entries kept, remainder discarded. Warning written to internal logs. |
| Numeric value out of range | Silently clamped to the nearest boundary, e.g. a price of -5 becomes 0. Warning written to internal logs. |
| Unrecognised enum value | The containing object is discarded. Validation error written to internal logs. |
| Format validation failed | The containing object is discarded, regardless of whether the field is required. Applies to any field with a documented format constraint, e.g. ISO 8601 dates, ISO 4217 currency codes, ISO 3166 country codes. Validation error written to internal logs. |
| Wrong field type or missing required field | The containing object is discarded. An invalid option is dropped from the list; an invalid top-level response is treated as a non-200 (request-type fallback applies). Centra does not coerce types. Validation error written to internal logs. |
| Unparseable or empty body | Treated as a non-200 response. Request-type fallback applies. |
Persisting Data For Orders
As a provider, you can configure attributes that Centra will store per order or shipment. These attributes are set by you in the orderCreated request.
Request Type: shippingOptions
Called by Centra when shipping options are needed for a customer to choose from.
Idempotency / Concurrency
This call has no idempotency requirements. Centra ensures that only one request per sessionId is in flight at any time.
shippingOptions: Request Context
To allow for a stateful integration optimized for speed, Centra provides the context the request is made from. Each context has varying requirements.
| Value | Timeout | Description |
|---|---|---|
| NOTIFY | 300 ms | Notification about an ongoing selection. Response payload is optional. |
| EXPRESS | 5 s | Initialise or update express payments. Response should ideally contain express-optimised options, or some options for Centra to configure. |
| CHECKOUT | 5 s | Made as part of checkout. A full response payload is expected. |
Caching
Centra may cache your response for sequential calls with an identical selection, address, and items, provided your last response used responseState = COMPLETE and none of the returned options have expired. Cached responses are kept for up to 5 minutes.
Error Handling
For signature verification errors, return HTTP 401 Unauthorized.
For structured errors, return HTTP 400 Bad Request with an error response body using one of the codes below. For any other non-200 response (including HTTP 5xx), Centra will treat the request as failed and fall back to internal Centra shipping options — no error body is expected or processed in that case.
| Error Code | Description |
|---|---|
| ADDRESS_INCOMPLETE | Address is missing fields that are mandatory for rate calculation in this country. Set addressFields to indicate which fields are missing. |
| ADDRESS_INVALID | Address fields are present but fail validation. Set addressFields to indicate which fields are invalid. |
| UNSUPPORTED_DESTINATION | Destination is correct but not shippable. |
| NO_RATES_AVAILABLE | Provider serves this destination but no shipping services are available for this specific request. |
| CONFIGURATION_ERROR | The integration is misconfigured and cannot fulfil requests until the configuration is corrected. Use message to describe what is wrong. |
| INTERNAL_ERROR | An unexpected error occurred on the provider side. Use message to provide details. |
Malformed 200 responses: an unparseable body or missing/invalid responseState is treated as a non-200 — Centra falls back to internal shipping options. For other constraint violations, see Response Validation.
Request Data Fields
| Field | Required | Type | Description |
|---|---|---|---|
| selectionId | N | string | Unique identifier for the current selection. |
| sessionId | Y | string | Unique identifier for the current session. Use this to correlate all requests belonging to the same customer session. |
| storeId | Y | int | Centra store identifier |
| market | Y | object | Market object |
| currencyCode | Y | string | Currency code |
| locale | Y | string | Locale code |
| totalValue | Y | number | Total item value of all the shipments combined |
| discounts | N | array | Array of discounts |
| optimizeFor | N | array | Array of display targets to optimize for |
| shipments | Y | array | Array of shipments to be sent |
| customer | N | object | Customer object for known customers |
shippingOptions / Request: Discount
Describes a discount that should give some form of free shipping to the customer.
| Field | Required | Type | Description |
|---|---|---|---|
| type | Y | string | Type of discount, always FREE in this version |
| level | Y | enum | Discount tier configured per Centra voucher. One of BASIC or PREMIUM. |
shippingOptions / Request: Market
| Field | Required | Type | Description |
|---|---|---|---|
| id | Y | int | Market identifier |
| name | Y | string | Name of the market |
shippingOptions / Request: Customer
| Field | Required | Type | Description |
|---|---|---|---|
| type | Y | string | Customer type. Always customer in B2C contexts. |
| id | Y | string | Customer identifier |
| Y | string | Customer email address | |
| phoneNumber | N | string | Customer phone number |
shippingOptions / Request: OptimizeFor
Some display contexts have limited UI space or reduced interaction capabilities. This allows you to tailor which options and features are presented for each context.
| Field | Required | Type | Description |
|---|---|---|---|
| type | Y | enum | The display context this entry applies to. See types. |
| optionsShown | N | int | How many options will be shown, if this is not given there is no set limit. |
| pickupSelectSupported | N | boolean | false = first location of each option will be used, if not given or true a pickup selector can be shown. |
| customerChoicesSupported | N | boolean | false = no customer choices will be shown, if not given or true customer choices can be shown. |
shippingOptions / Request: OptimizeFor Type
| Value | Description |
|---|---|
| applepay | Apple Pay express checkout |
| googlepay | Google Pay express checkout |
| ams | Centra admin panel checkout |
shippingOptions / Request: Shipment
| Field | Required | Type | Description |
|---|---|---|---|
| id | Y | string | Unique identifier for this shipment |
| value | Y | number | Total item value of this specific shipment |
| origin | Y | object | Address items will be shipped from |
| destination | Y | object | Address items will be shipped to |
| items | Y | array | Array of items included in the shipment |
Shared: Address
| Field | Required | Type | Description |
|---|---|---|---|
| lines | Y | array | Street address lines |
| locality | Y | string | City or locality name |
| administrativeArea | N | string | State or province |
| postalCode | Y | string | Postal or ZIP code |
| countryCode | Y | string | ISO 3166-1 alpha-2 country code |
Shared: Item
| Field | Required | Type | Description |
|---|---|---|---|
| lineId | Y | string | Unique identifier for this item in the shipment |
| sku | Y | string | SKU of the item |
| variantName | Y | string | Name of the variant |
| productName | Y | string | Name of the product |
| productId | Y | string | Centra product identifier |
| variantId | Y | string | Centra variant identifier |
| quantity | Y | int | Quantity of the item in the shipment |
| unitPrice | Y | number | Unit price of the item in the shipment |
| unitOriginalPrice | Y | number | Original unit price of the item in the shipment |
| weightGrams | N | number | Weight of the item in grams, if configured |
| lengthMm | N | number | Length of the item in millimetres, if configured |
| widthMm | N | number | Width of the item in millimetres, if configured |
| heightMm | N | number | Height of the item in millimetres, if configured |
| harmonizedCommodityCode | Y | string | Harmonized System (HS) commodity code for customs purposes |
| countryOfOrigin | Y | string | Country code where the item was manufactured |
| imageUrl | N | string | URL to the primary product image for this item |
| attributes | N | object | Dynamic object with configurable product attributes related to shipping |
Success Response
| Field | Required | Type | Description |
|---|---|---|---|
| responseState | Y | enum | NOTICE, PARTIAL or COMPLETE |
| data | N | object | Shipping options for the requested selection |
shippingOptions / Response: responseState
| Value | Description |
|---|---|
| NOTICE | Only accepted for requestContext = NOTIFY, signals response does not have options, can write session level customData, a follow-up call will be made later to retrieve options. |
| PARTIAL | Accepted for all requestContext, at least one option available but more can exist shortly. Centra never caches this response. |
| COMPLETE | Accepted for all requestContext. The response is considered complete. Centra may cache the response for identical selections so long as the option expiry has not passed, up to 5 minutes. |
shippingOptions / Response: Success
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| shipments | N | array | Shipments with options, one per request shipment. | |
| omniOptions | N | array | ≤ 25 | Shipping options backed by Centra brick-and-mortar stores. Not bound to shipments — use when a physical store can fulfill or accept pickup for the entire order. |
| optimizeFor | N | array | Per-target option overrides for limited display contexts. Each entry replaces the standard options for a specific display target. See OptimizeFor. | |
| customData | N | array | ≤ 20 | Arbitrary key/value metadata to attach to the response. |
shippingOptions / Response: Shipment
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| id | Y | string | Unique identifier for this shipment, matching the request | |
| options | Y | array | ≤ 25 | Shipping options for this shipment |
| preselectedOption | N | string | ≤ 128 | ID of the option to preselect. Defaults to the first option if not specified. |
shippingOptions / Response: OptimizeFor
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| type | Y | string | Unique identifier for this service | |
| options | Y | array | Shipping options for a specific service | |
| preselectedOption | N | string | ≤ 128 | ID of the option to preselect. Defaults to the first option if not specified. |
shippingOptions / Response: Option
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| id | Y | string | ≤ 128 | Unique identifier for the shipping option |
| displayName | Y | string | ≤ 50 | Display name for the shipping option |
| price | Y | number | ≥ 0 | Price of the shipping option |
| originalPrice | N | number | ≥ 0 | Pre-discount price. Defaults to price if omitted |
| currencyCode | Y | string | ISO 4217 | Currency code for the shipping option |
| carrierName | Y | string | ≤ 100 | Name of the carrier for the shipping option |
| serviceCode | Y | string | ≤ 100 | Code for the shipping service |
| deliveryType | Y | enum | Delivery type indicating how the shipment reaches the customer | |
| description | N | string | ≤ 120 | Description of the shipping option |
| iconUrl | N | string | ≤ 255 | URL to an icon for the shipping option |
| etd | N | object | Estimated time of delivery for the shipping option | |
| requiresLocation | Y | boolean | Whether the customer must select a pickup location for this option | |
| locations | N | array | ≤ 25 | Nearby pickup locations. May be absent or empty even when requiresLocation is true — locations can also be fetched via optionLocations. |
| labels | N | array | ≤ 10 | Labels to show on the option |
| customerChoices | N | array | ≤ 10 | Choices that can be made by the customer |
| expireAfter | N | string | ISO 8601 | Datetime after which this option should no longer be offered |
| brickAndMortar | N | number | ID of a Centra brick-and-mortar store that may fulfill the order | |
| customData | N | array | ≤ 20 | Arbitrary key/value pairs to attach to the option |
shippingOptions / Response: DeliveryType
| Value | Description |
|---|---|
| TO_DOOR | The parcel is delivered directly to the customer's address by a carrier. |
| PICKUP | The customer collects the parcel from a designated pickup point. |
| LOCKER | The parcel is delivered to an automated parcel locker. |
| MAILBOX | A small parcel or letter-sized shipment delivered directly into the customer's physical mailbox. |
| OTHER | Catch-all for delivery types not covered by the values above. |
shippingOptions / Response: Custom Data
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| key | Y | string | ≤ 128 | Data key |
| value | Y | string | ≤ 255 | Data value |
shippingOptions / Response: ETD
Your estimate of when the shipment will arrive. This is your broad estimate, not a customer-chosen slot.
At least one field must be provided. If custom is present, it takes precedence and is shown to the customer in place of any derived label from relative or absolute.
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| relative | N* | object | Transit time as a range of time units. | |
| absolute | N* | object | Arrival as a date/time range. | |
| custom | N* | string | ≤ 120 | Free-form delivery estimate shown to the customer, e.g. "Delivered by Christmas". Takes precedence over relative and absolute when present. |
shippingOptions / Response: ETD Relative
Transit time as a range, e.g. "1–3 business days".
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| units | Y | enum | HOURS, DAYS, BUSINESS_DAYS, or WEEKS | |
| min | Y | int | ≥ 0 | Minimum transit time |
| max | Y | int | ≥ 0 | Maximum transit time |
shippingOptions / Response: ETD Absolute
Arrival as an absolute date/time range.
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| from | Y | string | ISO 8601 | Earliest estimated arrival (with timezone) |
| to | Y | string | ISO 8601 | Latest estimated arrival (with timezone) |
shippingOptions / Response: Location
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| id | Y | string | ≤ 128 | Unique identifier for the pickup location |
| displayName | Y | string | ≤ 50 | Name of the location |
| address | N | object | Address of the pickup location | |
| latitude | N | number | Geographic latitude | |
| longitude | N | number | Geographic longitude | |
| distance | N | array | ≤ 2 | Distance entries from the shipping address to this location, one per travel mode |
| openingHours | N | object | Opening hours with regular periods and special day exceptions. | |
| openingHoursText | N | string | ≤ 120 | Opening hours text |
| brickAndMortar | N | number | ID of a Centra brick-and-mortar store that may fulfill the order. | |
| customData | N | array | ≤ 20 | Arbitrary key/value pairs to attach to the location |
shippingOptions / Response: Location Distance
At least one of meters or minutes must be provided.
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| mode | Y | enum | DRIVING or WALKING | |
| meters | N | integer | ≥ 0 | Distance in meters |
| minutes | N | integer | ≥ 0 | Estimated travel time in minutes |
shippingOptions / Response: Location Opening Hours
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| periods | N | array | ≤ 14 | Regular weekly hours as a list of open/close periods. Each period has an open point and an optional close point (null means open 24 hours). A period can span midnight. |
| specialDays | N | array | ≤ 30 | Exceptions to the regular schedule (holidays, closures, etc.). |
Each period point (open / close):
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| day | Y | int | 0–6 | Day of week: 0 = Sunday, 1 = Monday, …, 6 = Saturday |
| hour | Y | int | 0–23 | Hour in 24-hour format |
| minute | Y | int | 0–59 | Minute |
Each specialDays entry:
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| date | Y | object | Calendar date with year, month (1–12), and day (1–31) sub-fields | |
| isClosed | Y | bool | Whether the location is closed for the entire day | |
| comment | N | string | ≤ 120 | Human-readable note (e.g. "Christmas Day") |
shippingOptions / Response: Label
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| type | Y | string | ≤ 32 | Label type name |
| displayName | Y | string | ≤ 50 | Short display name for the label |
| description | N | string | ≤ 120 | Description of what the label means |
| iconUrl | N | string | ≤ 255 | URL for icon to show on option |
shippingOptions / Response: Customer Choice
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| id | Y | string | ≤ 128 | Choice identifier |
| displayName | Y | string | ≤ 50 | Customer-facing label |
| description | Y | string | ≤ 120 | Explanatory text |
| type | Y | enum | One of INPUT, CHECKBOX, CHOICE, or TIMESLOT | |
| default | N | string | ≤ 128 | For INPUT: value shown in input box, defaults to empty. For CHOICE and TIMESLOT: the option with the given key will be selected, defaults to first option. For CHECKBOX: "1" for checked, defaults to unchecked. |
| options | N* | array | ≤ 10 | List of choices. Required when type is CHOICE or TIMESLOT. |
| price | N | number | ≥ 0 | Additional price added if the customer selects a non-default value. |
shippingOptions / Response: Customer Choice Option
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| key | Y | string | ≤ 128 | Choice identifier |
| displayName | Y | string | ≤ 50 | Customer-facing label |
| description | Y | string | ≤ 120 | Explanatory text |
| price | N | number | ≥ 0 | Overrides the price on the parent Customer Choice if set. |
shippingOptions / Response: Error
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| code | Y | enum | Error code. See error codes. | |
| message | Y | string | ≤ 1000 | Internal error message intended for logs and back-office operators. May be technical. |
| publicMessage | N | string | ≤ 255 | Customer-facing error message shown in the storefront. Should be tailored to the request locale. Falls back to a Centra-provided generic message if omitted. |
| addressFields | N | array | ≤ 10 | Present on ADDRESS_INCOMPLETE and ADDRESS_INVALID errors. Array of field name strings identifying which fields are missing or invalid, e.g. ["postalCode", "administrativeArea"] |
| customData | N | array | ≤ 20 | Arbitrary key/value metadata for custom provider integrations that require data beyond the standard contract. |
Example Request
Example request with two shipments.
{
"requestType": "shippingOptions",
"requestContext": "CHECKOUT",
"data": {
"selectionId": "sel-abc123def456",
"sessionId": "sess-xyz789abc",
"storeId": 1,
"market": {
"id": 3,
"name": "US Market"
},
"currencyCode": "USD",
"locale": "en-US",
"discounts": [
{"type": "FREE", "level": "BASIC"},
{"type": "FREE", "level": "PREMIUM"}
],
"optimizeFor": [
{"type": "applepay", "optionsShown": 5, "pickupSelectSupported": false}
],
"totalValue": 89.97,
"shipments": [
{
"id": "shipment-1",
"value": 59.98,
"origin": {
"countryCode": "US",
"administrativeArea": "NJ",
"locality": "East Hanover",
"postalCode": "07936",
"lines": ["27 Merry Ln", "apt. 111"]
},
"destination": {
"countryCode": "US",
"administrativeArea": "CA",
"locality": "San Francisco",
"postalCode": "94105",
"lines": ["123 Market St"]
},
"items": [
{
"lineId": "line-1",
"sku": "TSHIRT-BLK-M",
"variantName": "Classic T-Shirt — Black, Medium",
"productName": "Classic T-Shirt",
"productId": "product-101",
"variantId": "variant-501",
"quantity": 2,
"unitPrice": 29.99,
"unitOriginalPrice": 39.99,
"weightGrams": 200,
"lengthMm": 300,
"widthMm": 250,
"heightMm": 50,
"harmonizedCommodityCode": "6109.10",
"countryOfOrigin": "PT",
"imageUrl": "https://example.centracdn.net/client/dynamic/images/1-some-product-image.jpg",
"attributes": {}
}
]
},
{
"id": "shipment-2",
"value": 29.99,
"origin": {
"countryCode": "US",
"administrativeArea": "OR",
"locality": "Florence",
"postalCode": "97439",
"lines": ["3281 Center Street"]
},
"destination": {
"countryCode": "US",
"administrativeArea": "CA",
"locality": "San Francisco",
"postalCode": "94105",
"lines": ["123 Market St"]
},
"items": [
{
"lineId": "line-2",
"sku": "TSHIRT-BLK-M",
"variantName": "Classic T-Shirt — Black, Medium",
"productName": "Classic T-Shirt",
"productId": "product-101",
"variantId": "variant-501",
"quantity": 1,
"unitPrice": 29.99,
"unitOriginalPrice": 39.99,
"weightGrams": 200,
"lengthMm": 300,
"widthMm": 250,
"heightMm": 50,
"harmonizedCommodityCode": "6109.10",
"countryOfOrigin": "PT",
"imageUrl": "https://example.centracdn.net/client/dynamic/images/1-some-product-image.jpg",
"attributes": {}
}
]
}
],
"customer": {
"type": "customer",
"id": "12345",
"email": "customer@example.com",
"phoneNumber": "+14155551234"
}
}
}
Example Response
Example Response: Per-Shipment with Optimizations
{
"responseState": "COMPLETE",
"data": {
"shipments": [
{
"id": "shipment-1",
"preselectedOption": "opt-dhl-express",
"options": [
{
"id": "opt-dhl-express",
"displayName": "DHL Express",
"price": 12.99,
"currencyCode": "USD",
"carrierName": "DHL",
"serviceCode": "EXPRESS",
"deliveryType": "TO_DOOR",
"requiresLocation": false,
"description": "Next business day delivery",
"iconUrl": "https://cdn.provider.com/icons/dhl.svg",
"etd": {
"relative": { "units": "BUSINESS_DAYS", "min": 1, "max": 1 },
"absolute": { "from": "2026-02-25T08:00:00-05:00", "to": "2026-02-25T18:00:00-05:00" }
},
"customerChoices": [
{
"id": "doorcode",
"displayName": "Doorcode",
"description": "Enter the doorcode for delivery",
"type": "INPUT"
}
]
},
{
"id": "opt-ups-pickup",
"displayName": "UPS Access Point",
"price": 5.99,
"currencyCode": "USD",
"carrierName": "UPS",
"serviceCode": "EXPRESS",
"deliveryType": "PICKUP",
"requiresLocation": true,
"description": "Next business day delivery",
"iconUrl": "https://cdn.provider.com/icons/ups.svg",
"etd": {
"relative": { "units": "BUSINESS_DAYS", "min": 1, "max": 1 },
"absolute": { "from": "2026-02-25T08:00:00-05:00", "to": "2026-02-25T18:00:00-05:00" }
},
"locations": [
{
"id": "opt-ups-pickup-loc-1",
"displayName": "UPS Access Point — Fitzgerald Ave",
"address": {
"lines": ["1215 Fitzgerald Ave"],
"locality": "San Francisco",
"administrativeArea": "CA",
"postalCode": "94124",
"countryCode": "US"
},
"latitude": 37.7320,
"longitude": -122.3891,
"distance": [{ "mode": "DRIVING", "meters": 320 }],
"openingHoursText": "Mon–Fri 07–22, Sat 09–14 / 15–18, Sun 10–16",
"openingHours": {
"periods": [
{ "open": { "day": 1, "hour": 7, "minute": 0 }, "close": { "day": 1, "hour": 22, "minute": 0 } },
{ "open": { "day": 2, "hour": 7, "minute": 0 }, "close": { "day": 2, "hour": 22, "minute": 0 } },
{ "open": { "day": 3, "hour": 7, "minute": 0 }, "close": { "day": 3, "hour": 22, "minute": 0 } },
{ "open": { "day": 4, "hour": 7, "minute": 0 }, "close": { "day": 4, "hour": 22, "minute": 0 } },
{ "open": { "day": 5, "hour": 7, "minute": 0 }, "close": { "day": 5, "hour": 22, "minute": 0 } },
{ "open": { "day": 6, "hour": 9, "minute": 0 }, "close": { "day": 6, "hour": 14, "minute": 0 } },
{ "open": { "day": 6, "hour": 15, "minute": 0 }, "close": { "day": 6, "hour": 18, "minute": 0 } },
{ "open": { "day": 0, "hour": 10, "minute": 0 }, "close": { "day": 0, "hour": 16, "minute": 0 } }
]
}
},
{
"id": "opt-ups-pickup-loc-2",
"displayName": "UPS Access Point — Diamond St",
"address": {
"lines": ["1228 Diamond St"],
"locality": "San Francisco",
"administrativeArea": "CA",
"postalCode": "94131",
"countryCode": "US"
},
"latitude": 37.7410,
"longitude": -122.4338,
"distance": [{ "mode": "DRIVING", "meters": 850 }],
"openingHoursText": "Mon–Fri 08–22, Sat 09–17, Sun 10–17"
}
]
}
]
},
{
"id": "shipment-2",
"preselectedOption": "opt-dhl-express",
"options": [
{
"id": "opt-dhl-express",
"displayName": "DHL Express",
"price": 8.99,
"currencyCode": "USD",
"carrierName": "DHL",
"serviceCode": "EXPRESS",
"deliveryType": "TO_DOOR",
"requiresLocation": false,
"description": "Next business day delivery",
"iconUrl": "https://cdn.provider.com/icons/dhl.svg",
"etd": {
"relative": { "units": "BUSINESS_DAYS", "min": 1, "max": 1 },
"absolute": { "from": "2026-02-25T08:00:00-05:00", "to": "2026-02-25T18:00:00-05:00" }
},
"customerChoices": [
{
"id": "doorcode",
"displayName": "Doorcode",
"description": "Enter the doorcode for delivery",
"type": "INPUT"
}
]
}
]
}
],
"omniOptions": [
{
"id": "opt-bike-express",
"displayName": "Bike Express",
"price": 20.99,
"currencyCode": "USD",
"carrierName": "BKE",
"serviceCode": "EXPRESS",
"deliveryType": "TO_DOOR",
"requiresLocation": false,
"description": "Same day delivery",
"iconUrl": "https://cdn.provider.com/icons/bke.svg",
"etd": {
"relative": { "units": "HOURS", "min": 2, "max": 4 }
},
"expireAfter": "2026-02-24T11:00:00Z",
"customerChoices": [
{
"id": "doorcode",
"displayName": "Doorcode",
"description": "Enter the doorcode for delivery",
"type": "INPUT"
}
],
"brickAndMortar": 123
},
{
"id": "opt-store-pickup",
"displayName": "Client Store San Francisco",
"price": 0.00,
"currencyCode": "USD",
"carrierName": "",
"serviceCode": "PICKUP",
"deliveryType": "PICKUP",
"requiresLocation": true,
"description": "Pickup from store",
"iconUrl": "https://cdn.provider.com/icons/pickup.svg",
"brickAndMortar": 123,
"locations": [
{
"id": "opt-store-pickup-loc-2",
"displayName": "Client Store — Diamond St",
"address": {
"lines": ["1228 Diamond St"],
"locality": "San Francisco",
"administrativeArea": "CA",
"postalCode": "94131",
"countryCode": "US"
},
"latitude": 40.7527,
"longitude": -73.9772,
"distance": [{ "mode": "DRIVING", "meters": 850 }],
"openingHoursText": "Mon–Fri 10–17, Sat 11–14",
"brickAndMortar": 123
}
]
}
],
"optimizeFor": [
{
"type": "applepay",
"preselectedOption": "opt-dhl-express",
"options": [
{
"id": "opt-dhl-express",
"displayName": "DHL Express",
"price": 18.99,
"currencyCode": "USD",
"carrierName": "DHL",
"serviceCode": "EXPRESS",
"deliveryType": "TO_DOOR",
"requiresLocation": false,
"description": "Next business day delivery",
"iconUrl": "https://cdn.provider.com/icons/dhl.svg",
"etd": {
"relative": { "units": "BUSINESS_DAYS", "min": 1, "max": 1 },
"absolute": { "from": "2026-02-25T08:00:00-05:00", "to": "2026-02-25T18:00:00-05:00" }
}
}
]
}
]
}
}
Example Response: Partial options to a EXPRESS request context
{
"responseState": "PARTIAL",
"data": {
"optimizeFor": [
{
"type": "applepay",
"preselectedOption": "opt-dhl-express",
"options": [
{
"id": "opt-dhl-express",
"displayName": "DHL Express",
"price": 18.99,
"currencyCode": "USD",
"carrierName": "DHL",
"serviceCode": "EXPRESS",
"deliveryType": "TO_DOOR",
"requiresLocation": false,
"description": "Next business day delivery",
"etd": {
"relative": { "units": "BUSINESS_DAYS", "min": 1, "max": 3 },
"absolute": { "from": "2026-02-25T08:00:00-05:00", "to": "2026-02-27T18:00:00-05:00" }
},
"customerChoices": [
{
"id": "doorcode",
"displayName": "Doorcode",
"description": "Enter the doorcode for delivery",
"type": "INPUT"
}
],
"expireAfter": "2026-02-24T10:10:00Z"
}
]
}
]
}
}
Example Response: Error (no rates)
No available rates for the given address and items — returns HTTP 400:
{
"error": {
"code": "NO_RATES_AVAILABLE",
"message": "No rates found for this destination",
"customData": [{ "key": "zone", "value": "EU-NORTH" }]
}
}
Example Response: Error (incomplete address)
Required address fields missing for rate calculation — returns HTTP 400:
{
"error": {
"code": "ADDRESS_INCOMPLETE",
"message": "postalCode and administrativeArea are required for US shipments",
"publicMessage": "Please enter your ZIP code and state to see shipping options.",
"addressFields": ["postalCode", "administrativeArea"]
}
}
Request Type: optionLocations
Called by Centra to retrieve pickup locations near a given address, for example to populate a location picker before the customer has selected a shipping option.
Idempotency / Concurrency
This call has no idempotency requirements. Centra may issue concurrent requests for different addresses.
Error Handling
For any response code other than HTTP 200 OK, Centra will show no pickup locations for the given address. For signature verification errors, return HTTP 401 Unauthorized.
Malformed 200 responses: an unparseable body, or data.locations missing or not an array, is treated as a non-200 — no pickup locations are shown. An empty array is valid and means no locations were found.
Request Data Fields
| Field | Required | Type | Description |
|---|---|---|---|
| selectionId | N | string | Unique identifier for the current selection. |
| sessionId | Y | string | Unique identifier for the current session. Use this to correlate all requests belonging to the same customer session. |
| optionId | Y | string | ID of the shipping option to retrieve pickup locations for |
| address | N | object | Address to find nearby pickup locations for |
| latitude | N | number | Geographic latitude of the customer for distance calculation |
| longitude | N | number | Geographic longitude of the customer for distance calculation |
Success Response
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| data | Y | object | Response data | |
| data.locations | Y | array | ≤ 25 | Array of location objects near the address |
Example Request
{
"requestType": "optionLocations",
"data": {
"selectionId": "sel-abc123def456",
"sessionId": "sess-xyz789abc",
"optionId": "opt-ups-pickup",
"address": {
"lines": ["123 Market St"],
"locality": "San Francisco",
"administrativeArea": "CA",
"postalCode": "94105",
"countryCode": "US"
},
"latitude": 37.7941,
"longitude": -122.3953
}
}
Example Response
{
"data": {
"locations": [
{
"id": "loc-ups-fitzgerald",
"displayName": "UPS Access Point — Fitzgerald Ave",
"address": {
"lines": ["1215 Fitzgerald Ave"],
"locality": "San Francisco",
"administrativeArea": "CA",
"postalCode": "94124",
"countryCode": "US"
},
"latitude": 37.7320,
"longitude": -122.3891,
"distance": [{ "mode": "DRIVING", "meters": 320 }],
"openingHoursText": "Mon–Fri 07–22, Sat 09–14 / 15–18, Sun 10–16",
"openingHours": {
"periods": [
{ "open": { "day": 1, "hour": 7, "minute": 0 }, "close": { "day": 1, "hour": 22, "minute": 0 } },
{ "open": { "day": 2, "hour": 7, "minute": 0 }, "close": { "day": 2, "hour": 22, "minute": 0 } },
{ "open": { "day": 3, "hour": 7, "minute": 0 }, "close": { "day": 3, "hour": 22, "minute": 0 } },
{ "open": { "day": 4, "hour": 7, "minute": 0 }, "close": { "day": 4, "hour": 22, "minute": 0 } },
{ "open": { "day": 5, "hour": 7, "minute": 0 }, "close": { "day": 5, "hour": 22, "minute": 0 } },
{ "open": { "day": 6, "hour": 9, "minute": 0 }, "close": { "day": 6, "hour": 14, "minute": 0 } },
{ "open": { "day": 6, "hour": 15, "minute": 0 }, "close": { "day": 6, "hour": 18, "minute": 0 } },
{ "open": { "day": 0, "hour": 10, "minute": 0 }, "close": { "day": 0, "hour": 16, "minute": 0 } }
]
}
},
{
"id": "loc-ups-diamond",
"displayName": "UPS Access Point — Diamond St",
"address": {
"lines": ["1228 Diamond St"],
"locality": "San Francisco",
"administrativeArea": "CA",
"postalCode": "94131",
"countryCode": "US"
},
"latitude": 37.7410,
"longitude": -122.4338,
"distance": [{ "mode": "DRIVING", "meters": 850 }],
"openingHoursText": "Mon–Fri 08–22, Sat 09–17, Sun 10–17"
}
]
}
}
Request Type: orderCreated
Called when a customer completes checkout using a shipping option provided by you.
Idempotency / Concurrency
This request may be sent multiple times by Centra for various reasons. Your implementation must treat repeated requests with the same sessionId as idempotent.
Caching
This request type is never cached.
Error Handling
In case of an unsuccessful response, Centra will retry the request after a 1-minute delay, up to 5 times.
Respond with HTTP 400 Bad Request and error code UNPROCESSABLE to tell Centra to stop retrying.
Reaching the retry limit or responding with the error code UNPROCESSABLE will result in the order being put on hold.
| Error Code | Description |
|---|---|
| UNPROCESSABLE | Not possible to process this order. |
The error response body uses the same structure as shippingOptions errors: an error root with code, message, and an optional customData array.
Request Data Fields
| Field | Required | Type | Description |
|---|---|---|---|
| selectionId | Y | string | Unique identifier for the selection. |
| sessionId | Y | string | Unique identifier for the current session. Use this to correlate all requests belonging to the same customer session. |
| orderNumber | Y | string | Centra order number |
| totalValue | Y | number | Total value of the order |
| currencyCode | Y | string | Currency code |
| locale | Y | string | Locale code |
| availableAttributes | Y | array | Array of strings listing attribute keys the provider may set on shipments |
| selectedOptions | Y | array | Array of selected options |
orderCreated / Request: Selected Option
| Field | Required | Type | Description |
|---|---|---|---|
| id | Y | string | Identifier of the selected shipping option, matching a previously returned option |
| price | Y | number | Price as provided for the option |
| finalPrice | Y | number | Final price of the selected option, which may differ from the price provided by the ESE if additional discounts were applied |
| location | N | object | Location reference, present when a pickup was selected |
| customerChoices | N | array | Array of customer choice values |
| shipments | Y | array | Array of shipments covered by this option |
orderCreated / Request: Shipment
| Field | Required | Type | Description |
|---|---|---|---|
| id | Y | string | Unique identifier for this shipment |
| origin | Y | object | Address items will be shipped from |
| destination | Y | object | Address items will be shipped to |
| items | Y | array | Array of items included in the shipment |
orderCreated / Request: Location Reference
| Field | Required | Type | Description |
|---|---|---|---|
| id | Y | string | Identifier of the selected pickup location |
orderCreated / Request: Customer Choice Value
| Field | Required | Type | Description |
|---|---|---|---|
| id | Y | string | Identifier of the customer choice |
| value | Y | string | Value selected or entered by the customer |
Response Data Fields
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| shipments | Y | array | Array of shipments, one per request shipment |
orderCreated / Response: Shipment
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| id | Y | string | ≤ 128 | Identifier matching the corresponding shipment in the request |
| attributes | N | array | ≤ 20 | Array of attributes to set on the shipment. Omit if there is nothing to set. |
orderCreated / Response: Attribute
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| key | Y | string | ≤ 128 | Attribute key; must match one of the values in availableAttributes from the request |
| value | Y | string | ≤ 2048 | Value to set for the attribute |
Example Request: Single Option Per Shipment
{
"requestType": "orderCreated",
"data": {
"selectionId": "asd123",
"sessionId": "sess-xyz789abc",
"orderNumber": "1234567890",
"totalValue": 123.45,
"currencyCode": "USD",
"locale": "en-US",
"availableAttributes": ["tos-id", "doorcode"],
"selectedOptions": [
{
"id": "opt-ups-pickup",
"price": 5.99,
"finalPrice": 5.99,
"location": { "id": "opt-ups-pickup-loc-2" },
"shipments": [
{
"id": "shipment-1",
"origin": {
"countryCode": "US",
"administrativeArea": "NJ",
"locality": "East Hanover",
"postalCode": "07936",
"lines": ["27 Merry Ln", "apt. 111"]
},
"destination": {
"countryCode": "US",
"administrativeArea": "CA",
"locality": "San Francisco",
"postalCode": "94105",
"lines": ["123 Market St"]
},
"items": [
{
"lineId": "line-1",
"sku": "TSHIRT-BLK-M",
"variantName": "Classic T-Shirt — Black, Medium",
"productName": "Classic T-Shirt",
"productId": "product-101",
"variantId": "variant-501",
"quantity": 2,
"unitPrice": 29.99,
"unitOriginalPrice": 39.99,
"weightGrams": 200,
"lengthMm": 300,
"widthMm": 250,
"heightMm": 50,
"harmonizedCommodityCode": "6109.10",
"countryOfOrigin": "PT",
"imageUrl": "https://example.centracdn.net/client/dynamic/images/1-some-product-image.jpg",
"attributes": {}
}
]
}
]
},
{
"id": "opt-dhl-express",
"price": 8.99,
"finalPrice": 7.99,
"customerChoices": [
{ "id": "doorcode", "value": "1579" }
],
"shipments": [
{
"id": "shipment-2",
"origin": {
"countryCode": "US",
"administrativeArea": "OR",
"locality": "Florence",
"postalCode": "97439",
"lines": ["3281 Center Street"]
},
"destination": {
"countryCode": "US",
"administrativeArea": "CA",
"locality": "San Francisco",
"postalCode": "94105",
"lines": ["123 Market St"]
},
"items": [
{
"lineId": "line-2",
"sku": "TSHIRT-BLK-M",
"variantName": "Classic T-Shirt — Black, Medium",
"productName": "Classic T-Shirt",
"productId": "product-101",
"variantId": "variant-501",
"quantity": 1,
"unitPrice": 29.99,
"unitOriginalPrice": 39.99,
"weightGrams": 200,
"lengthMm": 300,
"widthMm": 250,
"heightMm": 50,
"harmonizedCommodityCode": "6109.10",
"countryOfOrigin": "PT",
"imageUrl": "https://example.centracdn.net/client/dynamic/images/1-some-product-image.jpg",
"attributes": {}
}
]
}
]
}
]
}
}
Example Response: Single Option Per Shipment
{
"data": {
"shipments": [
{
"id": "shipment-1",
"attributes": [
{ "key": "tos-id", "value": "asd123" }
]
},
{
"id": "shipment-2",
"attributes": [
{ "key": "tos-id", "value": "qwe987" },
{ "key": "doorcode", "value": "1579" }
]
}
]
}
}
Example Request: Single Option for Multiple Shipments
{
"requestType": "orderCreated",
"data": {
"selectionId": "asd123",
"sessionId": "sess-xyz789abc",
"orderNumber": "1234567890",
"totalValue": 123.45,
"currencyCode": "USD",
"locale": "en-US",
"availableAttributes": ["tos-id", "doorcode"],
"selectedOptions": [
{
"id": "opt-dhl-express",
"price": 8.99,
"finalPrice": 7.99,
"customerChoices": [
{ "id": "doorcode", "value": "1579" }
],
"shipments": [
{
"id": "shipment-1",
"origin": {
"countryCode": "US",
"administrativeArea": "NJ",
"locality": "East Hanover",
"postalCode": "07936",
"lines": ["27 Merry Ln", "apt. 111"]
},
"destination": {
"countryCode": "US",
"administrativeArea": "CA",
"locality": "San Francisco",
"postalCode": "94105",
"lines": ["123 Market St"]
},
"items": [
{
"lineId": "line-1",
"sku": "TSHIRT-BLK-M",
"variantName": "Classic T-Shirt — Black, Medium",
"productName": "Classic T-Shirt",
"productId": "product-101",
"variantId": "variant-501",
"quantity": 2,
"unitPrice": 29.99,
"unitOriginalPrice": 39.99,
"weightGrams": 200,
"lengthMm": 300,
"widthMm": 250,
"heightMm": 50,
"harmonizedCommodityCode": "6109.10",
"countryOfOrigin": "PT",
"imageUrl": "https://example.centracdn.net/client/dynamic/images/1-some-product-image.jpg",
"attributes": {}
}
]
},
{
"id": "shipment-2",
"origin": {
"countryCode": "US",
"administrativeArea": "OR",
"locality": "Florence",
"postalCode": "97439",
"lines": ["3281 Center Street"]
},
"destination": {
"countryCode": "US",
"administrativeArea": "CA",
"locality": "San Francisco",
"postalCode": "94105",
"lines": ["123 Market St"]
},
"items": [
{
"lineId": "line-2",
"sku": "TSHIRT-BLK-M",
"variantName": "Classic T-Shirt — Black, Medium",
"productName": "Classic T-Shirt",
"productId": "product-101",
"variantId": "variant-501",
"quantity": 1,
"unitPrice": 29.99,
"unitOriginalPrice": 39.99,
"weightGrams": 200,
"lengthMm": 300,
"widthMm": 250,
"heightMm": 50,
"harmonizedCommodityCode": "6109.10",
"countryOfOrigin": "PT",
"imageUrl": "https://example.centracdn.net/client/dynamic/images/1-some-product-image.jpg",
"attributes": {}
}
]
}
]
}
]
}
}
Example Response: Single Option for Multiple Shipments
{
"data": {
"shipments": [
{
"id": "shipment-1",
"attributes": [
{ "key": "tos-id", "value": "qwe987" },
{ "key": "doorcode", "value": "1579" }
]
},
{
"id": "shipment-2",
"attributes": [
{ "key": "tos-id", "value": "qwe987" },
{ "key": "doorcode", "value": "1579" }
]
}
]
}
}
Example Error Response
Will place the order on hold in Centra, preventing further processing.
{
"error": {
"code": "UNPROCESSABLE",
"message": "No provider for given destination.",
"customData": [{ "key": "reason", "value": "country_not_serviced" }]
}
}
Request Type: testConnection
Verifies that request signing is working correctly and that the integration endpoint is reachable and configured.
Centra sends this request automatically when the integration is created or its configuration is updated.
Respond with HTTP 200 OK and { "data": { "status": "ok" } } on success.
Request Data Fields
| Field | Required | Type | Description |
|---|---|---|---|
| test | Y | string | Unicode test string sent by Centra |
Response Data Fields
| Field | Required | Type | Constraints | Description |
|---|---|---|---|---|
| data | Y | object | Response data. | |
| data.status | Y | string | Must be "ok". |
Any response that does not parse as valid JSON, is missing data.status, or has a data.status value other than "ok" is treated as a failed test.
Response Codes
| Status | Meaning |
|---|---|
| 200 OK | Connection and signing verified successfully. |
| 401 Unauthorized | Signature verification failed. Check that the signing secret is correctly configured on both sides. |
| Any other | Test failed. Centra will report the connection as unsuccessful. |
Example Request
{
"requestType": "testConnection",
"data": {
"test": "Héllo Wörld Zażółć gęślą jaźń こんにちは世界 Björk säger: ångström är en enhet. Pokój wszystkim! 日本語テスト。"
}
}
Example Success Response
{
"data": {
"status": "ok"
}
}
Example Error Response
HTTP 401 Unauthorized with empty payload — returned when the request signature cannot be verified.