Call Center API
REST · JSON v1.0 17 October 2019

Call Center API

Connect your agent to incoming calls and show them what the caller has been doing: pages viewed, current cart, existing orders. Carts and orders created by the agent are tied back to the call so you can measure their performance.

#1 Introduction

The Optico Call Center API gives your agents live information about every incoming call: the visitor's current page, prior views, the current cart and any existing orders. It pairs with the Cart API so your agents can also create or edit orders and carts from their interface.

#How It Works

When a call reaches your call center, your system queries /agent-api/callStart with the caller phone, destination phone and start time. Optico responds with the matching call record and everything it knows about the visitor: their journey, page views, cart contents and any open orders. Your agent UI can render this as the call rings.

By binding carts and orders to agents, Optico produces statistics on agent performance: cart value evolution after an agent call, orders placed through the phone channel, conversion rates, and more.

Base URL https://www.optico.fr

#Transport & Conventions

MethodAll endpoints use POST
Content-Typeapplication/x-www-form-urlencoded
Response formatapplication/json
Parameter namescamelCase in requests and responses
Related API The Call Center API is strongly connected to the Cart API. Once you know the agent and the callId, you can use Cart API endpoints to attach or edit orders and carts on behalf of the agent.

#2 Getting Started

  1. Create an account on www.optico.fr: you will receive a username, password, the Call Center API key (under Manage APIs in the admin interface), and access to the backend platform for management.
  2. Connect your agent to the call via /agent-api/callStart, using one of the two routing strategies described below.
  3. Use the Cart API to add or edit carts and orders from the agent side, providing the agent and callId parameters to attach the objects to the correct call.
  4. Receive updates by webhook: configure a URL where Optico will POST new views, cart and order changes during the call.

#Agent Routing: Two Strategies

Known agent at answer time
Pass the agent parameter directly on the callStart request.
Agent assigned later
Call callStart without agent, then call setAgentToCall once the agent is known.

#3 Authentication

Every request must include your apiKey as a POST field. The Call Center API key is unique across all of your registered domains and can be found in the Optico admin under Manage APIs.

Example
apiKey=b7e2c8a14f9d3650a1e7c4d8b2f6a395e
If the API key is missing or invalid, every endpoint returns status: "NOK" with an error message.

#4 Errors

All responses include a status field. On success it is "OK"; on failure it is "NOK" and an error field carries the message.

json
{ "status": "NOK", "error": "Invalid API key `b7e2c8a14f9d`" }
FieldWhen presentDescription
statusAlways"OK" on success, "NOK" on error.
resultsNbSuccessNumber of records returned in results.
resultsSuccessArray of records. See each endpoint for its response shape.
errorErrorDescription of the failure.

#5 Endpoints

EndpointMethodPurpose
/agent-api/callStartPOSTMatch an incoming call to its Optico record and return the full call context.
/agent-api/setAgentToCallPOSTAttach an agent to a previously-started call, identified by callId.
Your webhook URLPOSTOptico pushes real-time updates (new view, updated cart, new or updated order) to a URL you configure.

#6 Concepts

ConceptDescription
CallAn incoming call reaching your call center, identified by a unique callId.
AgentA call-center operator identified by their Optico username (usually an email).
ViewA page the caller has loaded during their session.
Current cartThe active cart associated with the caller's session, if any.
OrderAny existing order tied to the caller's session.

#7 POST /agent-api/callStart

Match an incoming call to its Optico record and return the visitor's full context. Use this as the first request when a call rings at your call center.

POSThttps://www.optico.fr/agent-api/callStart

Flow

Your PBX sends POST /agent-api/callStart with callerPhone, destinationPhone, startDate to Optico API
Optico API returns callId, call attribution, views[], currentCart, orders[]
If the agent is already known, include agent on the request to attach in one step.

Request Parameters

ParameterTypeDescription
apiKeyrequiredstringThe Call Center API key. Example: b7e2c8a14f9d3650a1e7c4d8b2f6a395e
callerPhoneoptionalstringCaller's phone. Omit or send "anonymous" for private numbers. E.g. 0033123456789.
destinationPhonerequiredstringThe destination phone the caller dialled. E.g. 0033123456789.
startDaterequiredstringCall start time in Y-m-d H:i:s. E.g. 2018-02-28 12:57:13.
agentoptionalstringAgent's Optico username. E.g. agent1@optico.fr.

Example Request

bash
curl -X POST https://www.optico.fr/agent-api/callStart \
  -d "apiKey=b7e2c8a14f9d3650a1e7c4d8b2f6a395e" \
  -d "callerPhone=0033612345678" \
  -d "destinationPhone=0033123456789" \
  -d "startDate=2018-02-28 12:57:13" \
  -d "agent=agent1@optico.fr"
<?php
$data = [
  'apiKey'           => 'b7e2c8a14f9d3650a1e7c4d8b2f6a395e',
  'callerPhone'      => '0033612345678',
  'destinationPhone' => '0033123456789',
  'startDate'        => '2018-02-28 12:57:13',
  'agent'            => 'agent1@optico.fr',
];
$ch = curl_init('https://www.optico.fr/agent-api/callStart');
curl_setopt_array($ch, [
  CURLOPT_POST           => true,
  CURLOPT_POSTFIELDS     => http_build_query($data),
  CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const params = new URLSearchParams({
  apiKey:           'b7e2c8a14f9d3650a1e7c4d8b2f6a395e',
  callerPhone:      '0033612345678',
  destinationPhone: '0033123456789',
  startDate:        '2018-02-28 12:57:13',
  agent:            'agent1@optico.fr',
});

const res = await fetch('https://www.optico.fr/agent-api/callStart', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: params,
});
const data = await res.json();

Success Response

FieldTypeDescription
statusstringOK
resultsNbintegerNumber of calls matched for the request.
resultsarrayFor each matched call: call, views, currentCart, orders.
json
{
  "status": "OK",
  "resultsNb": 1,
  "results": [
    {
      "call": {
        "id": 22122563,
        "startDate": "2018-01-02 09:29:27",
        "status": "OK_OUTCALL",
        "source": "Adwords",
        "referrer": null,
        "Keyword": "optico tracking",
        "agent": null
      },
      "views": [
        { "id": 568536624, "pageTitle": "Page title",  "url": "http://www.test.com/test.html",  "createdAt": "2018-01-02 09:25:41" },
        { "id": 568536667, "pageTitle": "Page title 2", "url": "http://www.test.com/test2.html", "createdAt": "2018-01-02 09:25:48" }
      ],
      "currentCart": {
        "id": 80359,
        "externalId": "5a4b477e3a05e",
        "isLoggedIn": true,
        "currency": "EUR",
        "status": 0,
        "totalCost": 1000,
        "productsNb": 2,
        "createdAt": "2018-01-02 09:49:46",
        "products": [
          { "id": 662315, "name": "Product 1", "quantity": 1, "costPerUnit": 896 },
          { "id": 662316, "name": "Product 2", "quantity": 1, "costPerUnit": 104 }
        ]
      },
      "orders": [
        { "id": 18676, "agent": "agent@optico.fr", "status": "Info", "isSale": false, "totalCost": 0, "createdAt": "2018-01-02 09:32:20", "products": [] }
      ]
    }
  ]
}

Error Response

FieldTypeDescription
statusstring"NOK"
errorstringError message, e.g. Invalid API key `b7e2c8a14f9d`.

#8 POST /agent-api/setAgentToCall

Attach an agent to a call already known to Optico, identified by callId. Use this when the agent is assigned after you have called callStart.

POSThttps://www.optico.fr/agent-api/setAgentToCall

Flow

On call answer
Your PBX sends POST /agent-api/callStart without agent to Optico API
Optico API returns callId, call context
When agent is assigned
Your PBX sends POST /agent-api/setAgentToCall with callId, agent to Optico API
Optico API returns { callId, agent }

Request Parameters

ParameterTypeDescription
apiKeyrequiredstringThe Call Center API key.
callIdrequiredintegerThe callId from callStart. E.g. 22122563.
agentrequiredstringAgent's Optico username. E.g. agent1@optico.fr.

Example Request

bash
curl -X POST https://www.optico.fr/agent-api/setAgentToCall \
  -d "apiKey=b7e2c8a14f9d3650a1e7c4d8b2f6a395e" \
  -d "callId=22122563" \
  -d "agent=agent1@optico.fr"
<?php
$ch = curl_init('https://www.optico.fr/agent-api/setAgentToCall');
curl_setopt_array($ch, [
  CURLOPT_POST           => true,
  CURLOPT_POSTFIELDS     => http_build_query([
    'apiKey' => 'b7e2c8a14f9d3650a1e7c4d8b2f6a395e',
    'callId' => 22122563,
    'agent'  => 'agent1@optico.fr',
  ]),
  CURLOPT_RETURNTRANSFER => true,
]);
$response = json_decode(curl_exec($ch), true);
const res = await fetch('https://www.optico.fr/agent-api/setAgentToCall', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    apiKey: 'b7e2c8a14f9d3650a1e7c4d8b2f6a395e',
    callId: '22122563',
    agent:  'agent1@optico.fr',
  }),
});
const data = await res.json();

Success Response

json
{
  "status": "OK",
  "resultsNb": 1,
  "results": [
    { "callId": 22122563, "agent": "agent1@optico.fr" }
  ]
}

#9 Webhooks

Configure a webhook URL and Optico will POST updates to it as soon as new information becomes available on an ongoing call: a new page view, a new or updated cart, a new or updated order.

Use when: you want the agent's screen to follow the caller's browsing and shopping activity during the call.

Delivery

MethodPOST to your webhook URL
ParameterrealtimeData (JSON payload, same shapes as callStart returns)
RoutingEvery payload includes the callId so you can route the update to the correct agent session.

Payload

FieldTypeDescription
callIdintegerThe call this update belongs to.
typestring"view", "cart", or "order".
viewobjectPresent when type = "view". Same shape as views[] in callStart.
cartobjectPresent when type = "cart". Same shape as currentCart in callStart.
orderobjectPresent when type = "order". Same shape as orders[] in callStart.

Example Payloads

One example per type. Only the matching sub-object is populated; the other two are null.

type = "view"

json
{
  "callId": 22122563,
  "type": "view",
  "view": {
    "id": 568536624,
    "pageTitle": "Page title",
    "url": "http://www.test.com/test.html",
    "createdAt": "2018-01-02 09:25:41"
  },
  "cart": null,
  "order": null
}

type = "cart"

json
{
  "callId": 22122563,
  "type": "cart",
  "view": null,
  "cart": {
    "id": 80359,
    "externalId": "5a4b477e3a05e",
    "isLoggedIn": true,
    "currency": "EUR",
    "status": 0,
    "totalCost": 1000,
    "productsNb": 2,
    "createdAt": "2018-01-02 09:49:46",
    "products": [
      { "id": 662315, "externalId": "SKU-001", "name": "Product 1", "quantity": 1, "costPerUnit": 896, "details": [] },
      { "id": 662316, "externalId": "SKU-002", "name": "Product 2", "quantity": 1, "costPerUnit": 104, "details": [] }
    ]
  },
  "order": null
}

type = "order"

json
{
  "callId": 22122563,
  "type": "order",
  "view": null,
  "cart": null,
  "order": {
    "id": 18676,
    "externalId": "ORD-2018-001",
    "cartId": 80359,
    "externalCartId": "5a4b477e3a05e",
    "agent": "agent1@optico.fr",
    "status": "Completed",
    "isSale": true,
    "currency": "EUR",
    "totalCost": 1000,
    "source": "Adwords",
    "createdAt": "2018-01-02 09:32:20",
    "products": [
      { "id": 662315, "externalId": "SKU-001", "name": "Product 1", "quantity": 1, "costPerUnit": 896, "details": [] }
    ]
  }
}