Register the sale

POST the completed order to Mulberry to create the warranty contract.

After the customer pays for coverage, your server must send the completed order to Mulberry's checkout endpoint. This call is what actually creates the warranty contract — selecting an offer and charging the customer does not. Once you have a successful response, the customer has a real, claimable warranty.

Skip this call and you ship a phantom warranty

If the customer pays for a plan but you never register the sale, no contract exists in Mulberry's system. There is no error at purchase time — the gap is invisible until the customer tries to file a claim and is turned away. Treat a successful POST /api/checkout response as the definition of "the warranty exists." If this call fails, the sale is not registered; retry it or flag the order for follow-up.

This page documents the exact request and response for POST /api/checkout. It assumes you have already collected the customer's offer selection — see Add a warranty to an order for capturing warranty_offer_id from the SDK.

Prerequisites

Before you make this call, make sure:

  1. The customer has completed checkout on your site and paid (including the warranty plan price).
  2. You captured the selected offer's warranty_offer_id from the SDK callback. See Add a warranty to an order.
  3. You have your API token (also called the access token) for the environment you're hitting. This is the server-side secret, not the public token. See Get your credentials.
  4. You have the order's id, the customer's email or phone, and a billing address.
🚧

Use the API token, not the public token

This endpoint authenticates with your server-side API token sent as a bearer token. The public token that initializes the browser SDK is a different credential — sending it here is not the supported path. Keep the API token server-side only and never ship it to the browser.

The endpoint

POST /api/checkout
Content-Type: application/json
Authorization: Bearer <your-api-token>

The base URL is https://www.getmulberry.com in production and https://staging.getmulberry.com in staging — so a production registration call is POST https://www.getmulberry.com/api/checkout. All paths on this page are relative to those hosts.

There is only one partner sale-registration route, and this is it — there is no versioned /api/v2/checkout. Send the request from your server, not the browser, so the API token stays secret.

Request body

Send a single JSON object describing the order, its line items, and the customer.

Required fields

FieldTypeNotes
order_id (or id)stringYour order identifier. Either key works; Mulberry reads order_id first, then falls back to id. This becomes the order's external id and is how duplicate submissions are detected. Omitting both returns 400 with "Id is a required field."
line_itemsarrayOne entry per warranty being registered. Must not be empty. See Line items below.
email (or phone)stringThe customer's contact. email is preferred. If you send only phone, Mulberry derives a placeholder email from it. Provide at least one.
billing_addressobjectRequired unless you send a shipping_address. Within it, state is required. See Addresses below.

Line items

Each entry in line_items identifies the offer the customer selected. For a custom integration, send the warranty_offer_id you captured from the SDK:

{
  "warranty_offer_id": "8f3c2a10-...-warranty-offer-uuid"
}

warranty_offer_id is the primary field Mulberry uses to match the line item to the offer the customer chose. It is the same value the SDK hands you in onWarrantySelect(offer) / onWarrantyToggle({ offer }) — see Add a warranty to an order.

👍

warranty_offer_id is the field that creates the contract

This is the single most important value in the whole payload. It ties the registered order to the exact plan the customer paid for. If it's missing or wrong, Mulberry can't attach a valid warranty and falls back to the hosted-cart flow (see below) instead of registering the sale.

Addresses

Send billing_address (or shipping_address). Mulberry reads the following fields; state is required.

FieldRequiredNotes
stateYesOmitting it returns 400 with "State is a required field."
zipRecommended
city, country, country_code, address1, address2, phone, first_name, last_nameOptionalRead when present.

If you send a shipping_address, its state and country are used for warranty validation in preference to the billing address, and a billing address is no longer required.

A complete example

{
  "order_id": "ORD-10428",
  "email": "[email protected]",
  "line_items": [
    { "warranty_offer_id": "8f3c2a10-...-warranty-offer-uuid" }
  ],
  "billing_address": {
    "first_name": "Ada",
    "last_name": "Lovelace",
    "address1": "12 Analytical Way",
    "city": "Brooklyn",
    "state": "NY",
    "zip": "11201",
    "country": "United States",
    "country_code": "US",
    "phone": "+15551234567"
  }
}
📘

Other accepted fields

The endpoint also accepts optional top-level fields such as cart_token, source_name, note, invoice_number, tax, and store. They're recorded with the order but are not required to register a warranty. Send what your platform has; leave the rest out.

Make the call

  1. Build the JSON body above using the order's id, the customer's email (or phone), the billing address, and a line_items entry containing the captured warranty_offer_id.
  2. POST it to /api/checkout with Content-Type: application/json and Authorization: Bearer <your-api-token>.
  3. Read the response.

On success you should now receive HTTP 200 with a body shaped like this:

{
  "success": true,
  "order_id": "ORD-10428",
  "data": { }
}
  • success is true.
  • order_id is the registered order's id.
  • data is the order detail Mulberry created — including the customer, the attached warranties, the external order id, and the order status.

A successful response means the warranty contract now exists and a confirmation is sent to the customer. This is your verification that the sale is registered.

👍

Verify the warranty registered

Confirm the call returned 200 with "success": true and a populated data.warranties array. Persist the returned order_id against your own order record so you can prove the warranty was created and reconcile later. If you ever need to confirm after the fact, the same order appears in the partner dashboard.

Hosted-cart fallback

When Mulberry can't attach a valid warranty from the payload — for example the offer wasn't matched, or some items still need a plan chosen — the same call returns HTTP 200 with a hosted-cart URL instead of an order:

{
  "success": true,
  "url": "https://www.getmulberry.com/carts/<retailer_uuid>/checkout/<order_id>",
  "warrantable_products": false
}

This is Mulberry's hosted page where the warranty selection is confirmed; sending the customer (or your UI) there completes the registration. It is not a separate API you POST to — it's the redirect target the same endpoint hands back when the sale couldn't be registered server-side. The warrantable_products value is a boolean flag indicating whether the hosted cart still has products eligible for a warranty.

🚧

A url response is not a registered warranty

If you get back url / warrantable_products instead of order_id / data, the contract has not been created yet. Check that your line_items carried the correct warranty_offer_id before relying on the hosted-cart fallback.

Don't double-submit

The endpoint is not idempotent, and there's no Idempotency-Key header. Mulberry dedupes by your order_id per retailer: re-POSTing the same id for the same account returns 400 with "... order already exists." rather than creating a second contract.

  • Submit each order exactly once.
  • If a call fails before you got a 200, it's safe to retry the same order_id — the duplicate guard only trips once an order has actually been created.

Errors

StatusBodyCause
400{ "message": { "validation_errors": ["Id is a required field."] } }No order_id or id.
400{ "message": "... order already exists." }Duplicate order_id for this retailer.
400{ "message": "... line_items must not be empty" }Empty line_items.
400{ "message": "Unable to process without a billing address." }No billing_address (and no shipping_address).
400{ "message": { "validation_errors": ["State is a required field."] } }Address is missing state.
401{ "message": "Unauthorized" }Token present but wrong, revoked, or for the wrong environment.
401{ "message": "Unauthorized request" }No Authorization header, or the token resolved to no retailer.
400{ "message": "Unable to check out. Please contact Mulberry Partner Success Team for further assistance" }Unexpected server-side error.
🚧

A failed call means an unregistered sale

Any non-200 response (or a 200 that returns the hosted-cart url instead of an order) means the warranty was not registered. Don't treat the customer as covered until you've seen "success": true with an order_id and data. Build retry-and-alert handling around this call.

Next step

You've now registered sales server-side. Before going live, run a real end-to-end test against staging and confirm the warranty appears — see Test and go live.