Contact lenses
Manage contact lenses
Creating a contact-lens subscription
Use the standard solicitation endpoint with a subscription_package cart item whose items array contains one contact_lens_subscription per eye. See Create the Subscription Solicitation for the surrounding flow (merchant, operator, personal data, webhook confirmation).
Endpoint /api/public/v1/subscriptions
Method POST
Swagger https://docs.sequra.com/update/reference/post_api-public-v1-subscriptions#/
Cart items
{
"cart_items": [
{
"reference": "PKG-001",
"name": "Contact lens package",
"price_with_tax": 50000,
"quantity": 1,
"type": "subscription_package",
"items": [
{
"reference": "CL-LEFT-001",
"type": "contact_lens_subscription",
"name": "Left contact lens",
"price_with_tax": 25000,
"subscription_price": 1000,
"quantity": 1,
"box_count": 4,
"exchange_cycle": 12,
"product_data": { "eye": "left" }
},
{
"reference": "CL-RIGHT-001",
"type": "contact_lens_subscription",
"name": "Right contact lens",
"price_with_tax": 25000,
"subscription_price": 1000,
"quantity": 1,
"box_count": 4,
"exchange_cycle": 12,
"product_data": { "eye": "right" }
}
]
}
]
}Send one contact_lens_subscription per eye. The typical case is two children — one for left, one for right — but you may send a single child with eye: "both" when the same lens is fitted on both eyes.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | yes | "contact_lens_subscription" for each per-eye item nested inside the package. |
box_count | integer | yes | Boxes the shopper is entitled to receive per subscription year for this eye. Must be ≥ 1. |
exchange_cycle | integer | no | Months between exchange windows. Defaults to 12. Pass 0 to disable the exchange window. |
product_data.eye | string | yes | "left", "right", or "both". |
The other fields (reference, name, price_with_tax, subscription_price, quantity) follow the same conventions as any subscription cart item.
Registering box deliveries
Endpoint /api/public/v1/subscriptions/:subscription_id/box_deliveries
Method POST
Swagger https://docs.sequra.com/update/reference/post_api-public-v1-subscriptions-id-box-deliveries#/
Payload
{
"deliveries": [
{
"cart_item_reference_uuid": "1a8c9f30-…-left",
"quantity": 1
},
{
"cart_item_reference_uuid": "1a8c9f30-…-right",
"quantity": 1
}
]
}Each entry references one contact-lens item by its reference_uuid (returned in the subscription response) and the boxes delivered in this call. A "both eyes" delivery is two entries — one per eye — even when the box totals match.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
deliveries | array | yes | Non-empty list of per-item entries. |
deliveries[].cart_item_reference_uuid | string | yes | The reference_uuid of the contact_lens_subscription item being delivered. |
deliveries[].quantity | integer | yes | Boxes delivered in this call. Must be ≥ 1. |
Response
{
"deliveries": [
{
"id": "06006609-…",
"type": "contact_lens_subscription",
"reference": "CL-LEFT-001",
"reference_uuid": "1a8c9f30-…-left",
"name": "Left contact lens",
"quantity": 1,
"box_count": 4,
"delivered_boxes": 1,
"remaining_boxes": 3,
"price_with_tax": { "value": 25000, "string": "250,00 €" },
"total_with_tax": { "value": 25000, "string": "250,00 €" },
"subscription_price": { "value": 1000, "string": "10,00 €" }
}
]
}The response includes a snapshot of every affected item after the call. delivered_boxes and remaining_boxes are scoped to the current subscription year (anchored on the subscription's activation date) and reset when the subscription enters its next year.
Idempotency
This endpoint is not idempotent. Two identical POSTs each succeed and delivered_boxes accumulates. The only safety net is the box_count cap: a request that would push delivered_boxes past box_count is rejected with 422. Deduplicate on the caller side if you need at-most-once semantics.
Error responses
| HTTP status | Reason |
|---|---|
400 | Malformed payload — missing deliveries, empty array, missing per-entry fields, non-positive quantity. |
401 | Missing or invalid HTTP Basic credentials, or the API account does not reference the subscription's merchant. |
404 | Subscription not found. |
409 | The subscription has no confirmed cart. |
422 | The cart_item_reference_uuid is unknown, points to a non-contact-lens item, or quantity exceeds the eye's remaining capacity for the current subscription year. |
For 422 over-delivery responses, the body includes the offending cart_item_reference_uuid and the boxes still remaining for that eye.
Reading delivery state
GET /api/public/v1/subscriptions/:id returns, for every contact-lens item nested inside a package, three counters:
box_count— entitled boxes per subscription year.delivered_boxes— boxes registered so far in the current year.remaining_boxes—box_count − delivered_boxes.
{
"last_persisted_cart": {
"cart_items": [
{
"type": "subscription_package",
"items": [
{
"type": "contact_lens_subscription",
"reference_uuid": "1a8c9f30-…-left",
"product_data": { "eye": "left" },
"box_count": 4,
"delivered_boxes": 1,
"remaining_boxes": 3
},
{
"type": "contact_lens_subscription",
"reference_uuid": "1a8c9f30-…-right",
"product_data": { "eye": "right" },
"box_count": 4,
"delivered_boxes": 1,
"remaining_boxes": 3
}
]
}
]
}
}Updated about 6 hours ago