Cart API
REST · JSON v1.0 07 November 2019

Cart API

Send real-time cart and order data to Optico. Associate purchases with visitor sessions and call center interactions.

Introduction #

The Cart API pushes cart and order data to Optico in real time. Paired with the Optico Tracking service, it links every purchase to the visitor's session, source, keywords, and any calls they make. Agents see the caller's live cart, order history, and browsing journey inside the call center interface, and Optico ties the resulting revenue back to the marketing spend that produced it.

Base URL https://www.optico.fr

Transport & Conventions

MethodAll endpoints use POST
Content-Typeapplication/x-www-form-urlencoded
Response formatapplication/json
Parameter namessnake_case in requests, camelCase in responses
Timeout5 seconds recommended
A Prestashop Plugin is available to integrate the Cart API directly into Prestashop. Contact Optico to request it.

Authentication #

Every request must include your key as a POST field. The key is unique across all of your registered domains and is issued when your account is created on www.optico.fr.

Example
key=b7e2c8a14f9d3650a1e7c4d8b2f6a395e

Errors #

Response envelope

Every request returns 200 OK with a JSON envelope. Branch on the status field rather than the HTTP status code.

Success

json
{ "status": "success" }

Error

json
{ "status": "error",
  "message": "Invalid API key" }

Common error messages

MessageCauseFix
Invalid API keyThe key is missing, revoked, or not registered for the calling domain.Verify the key in your Optico account under Manage APIs.
Missing required parameterOne or more required fields are absent or empty.Log the submitted payload and compare it against the parameters table for the endpoint.
Invalid products formatThe products array could not be parsed.Submit a valid array of product objects (see Products object).
Unknown visit_idThe visit_id does not match any tracked visit.Confirm the Optico Tracking cookie is set before posting cart/order data.

Idempotency

Both endpoints are idempotent on your id field: re-submitting the same cart or order id updates the existing record instead of creating a duplicate. This is a deliberate design so your integration can safely retry on transient failures.

Retries & timeouts

Use a 5-second client timeout. A network timeout or an HTTP 5xx response is safe to retry with exponential backoff (for example 1s, 2s, 4s) because the endpoints are idempotent. Do not retry on a JSON {"status":"error"} body. The request was received and rejected; inspect the message and fix the payload.

Rate limits

No fixed public rate limit is enforced for normal traffic. Call the API on every cart and order change. If you plan a bulk backfill or expect sustained traffic above a few hundred requests per second, contact Optico in advance to size the channel for your account.

Endpoints #

EndpointMethodPurpose
/api/customer-cartPOSTInsert or update a shopping cart. Call on every cart change.
/api/customer-orderPOSTInsert or update an order. Call on every order creation and status change.

POST /api/customer-cart #

POSThttps://www.optico.fr/api/customer-cart

Insert or update a shopping cart. Call this endpoint on every cart change.

Parameters

NameTypeDescription
keystringRequired Your API key (shared across all your domains): "b7e2c8a14f9d3650a1e7c4d8b2f6a395e"
idstringRequired Your cart id: "1"
currencystringRequired ISO 4217 currency code: "EUR"
visit_idstringRequired Visitor session id. See Integration for how to read it from cookies: "3617898c651df0f8617f70a0"
productsarrayRequired Cart items. See the Products object section for the object structure.
is_logged_inintegerRequired 1 if the buyer is authenticated, 0 otherwise.
call_idintegerOptional Current call id when working alongside the Call Center API; links the cart to that call.
agentstringOptional Current agent username when working alongside the Call Center API; links the cart to that agent.

Example request

bash
curl -X POST https://www.optico.fr/api/customer-cart \
  --max-time 5 \
  -d "key=b7e2c8a14f9d3650a1e7c4d8b2f6a395e" \
  -d "id=1" \
  -d "currency=EUR" \
  -d "visit_id=3617898c651df0f8617f70a0" \
  -d "is_logged_in=1" \
  --data-urlencode 'products[0][id]=1' \
  --data-urlencode 'products[0][name]=Product 1' \
  --data-urlencode 'products[0][quantity]=2' \
  --data-urlencode 'products[0][price]=29.99'
// Read visit ID from cookie (JS: optico_visitId / API: optico_visit_id)
$visitId = $_COOKIE['optico_visit_id'] ?? '';

$params = [
    'key'          => 'b7e2c8a14f9d3650a1e7c4d8b2f6a395e',
    'id'           => '1',
    'currency'     => 'EUR',
    'visit_id'     => $visitId,
    'is_logged_in' => 1,
    'products'     => [[
        'id'       => 1,
        'name'     => 'Product 1',
        'quantity' => 2,
        'price'    => 29.99,
        'details'  => 'some product details',
    ]],
];

$ch = curl_init('https://www.optico.fr/api/customer-cart');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($params),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 5,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
// Node 18+ (built-in fetch). Read visit_id from your cookie store.
const params = new URLSearchParams();
params.append('key', 'b7e2c8a14f9d3650a1e7c4d8b2f6a395e');
params.append('id', '1');
params.append('currency', 'EUR');
params.append('visit_id', visitId);
params.append('is_logged_in', '1');
params.append('products[0][id]', '1');
params.append('products[0][name]', 'Product 1');
params.append('products[0][quantity]', '2');
params.append('products[0][price]', '29.99');

const res = await fetch('https://www.optico.fr/api/customer-cart', {
  method: 'POST',
  body:   params,
  signal: AbortSignal.timeout(5000),
});
const data = await res.json();

Response

Success

json
{ "status": "success" }

Error

json
{ "status": "error",
  "message": "..." }

POST /api/customer-order #

POSThttps://www.optico.fr/api/customer-order

Insert or update an order. Call this endpoint when an order is created and on every status change.

Parameters

NameTypeDescription
keystringRequired Your API key: "b7e2c8a14f9d3650a1e7c4d8b2f6a395e"
idstringRequired Your order id: "1"
cart_idstringRequired Id of the cart that produced this order: "1"
currencystringRequired ISO 4217 currency code: "EUR"
visit_idstringRequired Visitor session id. See Integration: "3617898c651df0f8617f70a0"
productsarrayRequired Order items. See the Products object section.
statusstringRequired Current order status: "Completed". Use consistent spelling and language; the same values must be declared in Optico under Agents / Paramètres.
call_idintegerOptional Current call id when working alongside the Call Center API.
agentstringOptional Current agent username when working alongside the Call Center API.

Example request

bash
curl -X POST https://www.optico.fr/api/customer-order \
  --max-time 5 \
  -d "key=b7e2c8a14f9d3650a1e7c4d8b2f6a395e" \
  -d "id=1" \
  -d "cart_id=1" \
  -d "currency=EUR" \
  -d "visit_id=3617898c651df0f8617f70a0" \
  -d "status=Completed" \
  --data-urlencode 'products[0][id]=1' \
  --data-urlencode 'products[0][name]=Product 1' \
  --data-urlencode 'products[0][quantity]=2' \
  --data-urlencode 'products[0][price]=29.99'
$visitId = $_COOKIE['optico_visit_id'] ?? '';

$params = [
    'key'      => 'b7e2c8a14f9d3650a1e7c4d8b2f6a395e',
    'id'       => '1',
    'cart_id'  => '1',
    'currency' => 'EUR',
    'visit_id' => $visitId,
    'status'   => 'Completed',
    'products' => [[
        'id'       => 1,
        'name'     => 'Product 1',
        'quantity' => 2,
        'price'    => 29.99,
    ]],
];

$ch = curl_init('https://www.optico.fr/api/customer-order');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($params),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 5,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const params = new URLSearchParams();
params.append('key', 'b7e2c8a14f9d3650a1e7c4d8b2f6a395e');
params.append('id', '1');
params.append('cart_id', '1');
params.append('currency', 'EUR');
params.append('visit_id', visitId);
params.append('status', 'Completed');
params.append('products[0][id]', '1');
params.append('products[0][name]', 'Product 1');
params.append('products[0][quantity]', '2');
params.append('products[0][price]', '29.99');

const res = await fetch('https://www.optico.fr/api/customer-order', {
  method: 'POST',
  body:   params,
  signal: AbortSignal.timeout(5000),
});
const data = await res.json();

Response

Success

json
{ "status": "success" }

Error

json
{ "status": "error",
  "message": "..." }

Products object #

Each item in the products array is a product object with the following keys:

FieldTypeDescription
idmixedRequiredProduct id from your catalogue: 1
namestringRequiredDisplay name: "Product 1"
quantityintegerRequiredNumber of units: 2
pricefloatRequiredUnit price: 29.99
detailsstring or arrayOptionalFree-form product information, displayed as-is in the agent dashboard. Can be a plain string or a nested array with any keys.

Details field examples

Simple string

PHP
'details' => 'some product details'

Nested array

PHP
'details' => [
  'color'      => 'blue',
  'dimensions' => [
    'width'  => '20cm',
    'height' => '20cm',
    'length' => '20cm'
  ]
]

Integration #

Getting the visit_id

The visit_id comes from the Optico Tracking service and identifies the visitor's session. Read it from the appropriate cookie depending on your tracking method:

Tracking methodCookie nameExample value
JS trackingoptico_visitId3617898c651df0f8617f70a0
API tracking (using the Optico PHP example)optico_visit_id3617898c651df0f8617f70a0

Integration flow

Tracking Setup
Your siteintegrates Optico Tracking → visit_id cookie is set on each page load
Cart Activity
Visitoradds / updates items in cart
Your sitePOSTs to /api/customer-cart with visit_id + products
Optico{ "status": "success" }
Order Placed
Visitorcompletes checkout
Your sitePOSTs to /api/customer-order with visit_id + cart_id + products + status
Optico{ "status": "success" }
Call
Visitorcalls a tracked phone number
Opticopushes cart + order data to agent dashboard in real time

Connecting carts and orders to calls

When a visitor calls while the Call Center API is active, you may have access to the current call_id and the handling agent username. Pass these optional fields to directly associate the cart or order record with the specific call and agent; this enriches the call timeline visible to agents.