Skip to main content
POST /v2/abandoned-cart-recovery/recover is the public endpoint a storefront calls when a customer clicks the recover-cart link in an automated abandoned-cart email. The endpoint takes the opaque recoveryToken from the URL, looks up the abandoned cart, and returns the cart contents so the storefront can re-hydrate the checkout exactly where the customer left off. The endpoint is unauthenticated by design — the recovery token is the auth. Tokens are single-purpose (cart-resume only), scoped to one cart, time-bound (7 days), and never carry PII in the URL. The cron that fires the recovery emails (which shops are eligible, how often, the email template) is operator-controlled and is documented in the operator runbook for cart abandonment — link will land once that runbook page ships.

When to use

Call this when your storefront loads a URL that contains a recover=<token> query string parameter (the recovery email links land on /cart?recover=<token>). On success, populate the customer’s cart state from the response. On failure, fall back to an empty cart and optionally surface a “this link has expired” notice.
Recovery tokens are random 24-character base64url-encoded strings. They are unique, indexed, and contain no PII (no email, no shop slug, no product names). The URL is safe to log at the storefront edge, in CDN access logs, and in analytics.

POST /v2/abandoned-cart-recovery/recover

Authentication

None — the recoveryToken is the auth. Tokens are single-use semantically (resumes the same cart) and rate-limited per IP (60 req/min).

Request body

FieldTypeRequiredDescription
recoveryTokenstringYesThe opaque token from the recovery URL (24 chars, base64url)

Example request

curl -X POST https://apiv3.droplinked.com/v2/abandoned-cart-recovery/recover \
  -H 'content-type: application/json' \
  -d '{ "recoveryToken": "kQ7bN3pXm2vR8sLwT4yC1zJh" }'

Response — 200 OK, cart found

{
  "found": true,
  "cart": {
    "cartId": "65f8a1b2c3d4e5f6a7b8c9aa",
    "shopId": "65f8a1b2c3d4e5f6a7b8c9bb",
    "shopSlug": "unstoppable",
    "lineItems": [
      {
        "productId": "prod_xyz",
        "skuId": "sku_xyz_red_m",
        "quantity": 2,
        "unitPriceCents": 2500
      }
    ],
    "cartTotalCents": 5000,
    "currency": "USD",
    "customerEmail": "buyer@example.com",
    "abandonedAt": "2026-06-10T18:23:00.000Z"
  }
}
FieldTypeDescription
foundtrueToken resolved to a recoverable cart
cart.cartIdstringThe cart’s _id — pass to checkout-intent on resume
cart.shopIdstringThe shop the cart belongs to
cart.shopSlugstringThe shop’s storefront slug — useful for redirecting to the right *.droplinked.io host if the link was opened on a different surface
cart.lineItemsarrayThe cart’s line items at abandonment time
cart.cartTotalCentsintPre-discount cart subtotal
cart.currencystringThree-letter ISO 4217
cart.customerEmailstringThe email address the recovery message was sent to — for pre-filling the contact form
cart.abandonedAtISO-8601When the cron flagged the cart as abandoned

Response — 404 Not Found, token not recognized or expired

{
  "found": false,
  "reason": "recovery_token_not_found_or_expired"
}
The endpoint returns a single failure reason (recovery_token_not_found_or_expired) so that the storefront cannot distinguish “this token never existed” from “this token has expired” from a timing or enumeration perspective. From the storefront’s POV the UX is the same in either case: surface a “this recovery link is no longer valid” notice and load an empty cart.

Error responses

StatusWhen
400Malformed body (missing recoveryToken, wrong type, length other than 24)
404Token not recognized or expired (see above)
429Rate limit exceeded for caller IP

Recovery URL format

The cron writes recovery URLs in this exact format:
https://{shopSlug}.droplinked.io/cart?recover=<recoveryToken>
The storefront SPA at that route reads the recover query parameter, calls this endpoint, and hydrates the cart from the response. If your custom storefront does not run on *.droplinked.io, you can still call this endpoint — the response includes cart.shopSlug so you can verify the link was intended for the surface that loaded it.

Expiration

Recovery tokens expire 7 days from cart abandonment. After expiry the token is permanently invalid — there is no re-issue. The customer would need to be served a fresh abandonment email (which can only be sent once per cart per the cron policy). The 7-day window is operator-tunable per shop in the cart-abandonment cron config, but defaults to 7 days for every shop.

Privacy

Recovery tokens are random 24-character base64url strings. They are unique, server-side indexed, and contain no PII — no email address, no shop slug, no product IDs, no order ID. The URL can safely appear in browser history, CDN access logs, and email-client preview-mode renderings without leaking customer state.
The cart record the token resolves to does contain the customer’s email — but that record is only accessible via the token, never via enumeration.
  • Checkout payment-intent resolver — the next step after the customer resumes their cart and proceeds to checkout.
  • Merchants overview — how cart recovery fits into the merchant’s order lifecycle.
  • Operator runbook — cart-abandonment cron config and email templates — coming.