curl --request GET \
--url https://api-eg.olimi.ai/api/v2/calls \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api-eg.olimi.ai/api/v2/calls"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api-eg.olimi.ai/api/v2/calls', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-eg.olimi.ai/api/v2/calls",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-eg.olimi.ai/api/v2/calls"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-eg.olimi.ai/api/v2/calls")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-eg.olimi.ai/api/v2/calls")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"message": "Calls fetched successfully",
"meta": {
"totalItems": 12,
"itemCount": 10,
"itemsPerPage": 10,
"totalPages": 2,
"currentPage": 1
},
"data": [
{
"id": "c41f8e27-3b9a-4d6e-8f15-2a7c9e0b4d63",
"callSid": "CA7d3f1c9e2b8a4f60d5e1c7b93a2f8e41d6",
"status": "answered",
"callType": "outbound",
"durationInSec": 184,
"isInterested": true,
"tags": [
"interested"
],
"tagsWithColors": [
{
"name": "interested",
"color": "#16A34A"
}
],
"customKeys": [
{
"key": "preferred_branch",
"value": "Nasr City"
}
],
"retryCount": 0,
"isFinal": true,
"createdAt": "2026-09-28T10:22:41.307Z",
"agent": {
"id": "0d6a3f7e-5b8c-4b1e-9a51-2f1d7c9e4a10",
"name": "Renewals Agent"
},
"contact": {
"id": "b2f7c4e1-8a3d-4c59-9e06-1d5a7f3b8c42",
"phoneNumber": "+201001234567",
"firstName": "Ahmed",
"lastName": "Hassan",
"callbackScheduled": false
},
"campaign": {
"id": "3e8b5d21-7c4a-4f96-a1d0-6b2e9c7f4a58",
"name": "September renewals",
"maxRetries": 2
},
"didNumber": {
"id": "d5a2e8c1-4f7b-4a93-b6d0-1e9c3f7a2b84",
"phoneNumber": "+20225550100"
},
"hasSummary": true,
"hasTranscript": true,
"hasRecording": true,
"isCallback": false
}
]
}{
"statusCode": 404,
"errorCode": "agent_not_found",
"message": "Agent not found"
}{
"statusCode": 404,
"errorCode": "agent_not_found",
"message": "Agent not found"
}{
"statusCode": 422,
"message": [
"name must be shorter than or equal to 100 characters"
],
"error": "Unprocessable Entity"
}List calls
Returns your call history, newest first, one page at a time, with search and filters.
curl --request GET \
--url https://api-eg.olimi.ai/api/v2/calls \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api-eg.olimi.ai/api/v2/calls"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api-eg.olimi.ai/api/v2/calls', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-eg.olimi.ai/api/v2/calls",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-eg.olimi.ai/api/v2/calls"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-eg.olimi.ai/api/v2/calls")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-eg.olimi.ai/api/v2/calls")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"message": "Calls fetched successfully",
"meta": {
"totalItems": 12,
"itemCount": 10,
"itemsPerPage": 10,
"totalPages": 2,
"currentPage": 1
},
"data": [
{
"id": "c41f8e27-3b9a-4d6e-8f15-2a7c9e0b4d63",
"callSid": "CA7d3f1c9e2b8a4f60d5e1c7b93a2f8e41d6",
"status": "answered",
"callType": "outbound",
"durationInSec": 184,
"isInterested": true,
"tags": [
"interested"
],
"tagsWithColors": [
{
"name": "interested",
"color": "#16A34A"
}
],
"customKeys": [
{
"key": "preferred_branch",
"value": "Nasr City"
}
],
"retryCount": 0,
"isFinal": true,
"createdAt": "2026-09-28T10:22:41.307Z",
"agent": {
"id": "0d6a3f7e-5b8c-4b1e-9a51-2f1d7c9e4a10",
"name": "Renewals Agent"
},
"contact": {
"id": "b2f7c4e1-8a3d-4c59-9e06-1d5a7f3b8c42",
"phoneNumber": "+201001234567",
"firstName": "Ahmed",
"lastName": "Hassan",
"callbackScheduled": false
},
"campaign": {
"id": "3e8b5d21-7c4a-4f96-a1d0-6b2e9c7f4a58",
"name": "September renewals",
"maxRetries": 2
},
"didNumber": {
"id": "d5a2e8c1-4f7b-4a93-b6d0-1e9c3f7a2b84",
"phoneNumber": "+20225550100"
},
"hasSummary": true,
"hasTranscript": true,
"hasRecording": true,
"isCallback": false
}
]
}{
"statusCode": 404,
"errorCode": "agent_not_found",
"message": "Agent not found"
}{
"statusCode": 404,
"errorCode": "agent_not_found",
"message": "Agent not found"
}{
"statusCode": 422,
"message": [
"name must be shorter than or equal to 100 characters"
],
"error": "Unprocessable Entity"
}hasSummary, hasTranscript, hasRecording and isCallback. For the summary, recording and transcript themselves, use Get a call.
Use meta.totalPages to know when you’ve fetched every page. All filters can be combined.
How search works
search is split into words. A call matches if any word matches:
- Contact name: the word appears in the contact’s first or last name, or is spelled similarly. Not case-sensitive.
- Phone number: a word made only of digits, optionally starting with
+, also matches the contact’s phone number when it contains it. Numbers are stored in E.164 form (+201001234567), so use digits as they appear there: no spaces, dashes or brackets. - Account code: the word equals the call’s account code exactly.
- Call reference: a word of 28 characters or more also matches the full
callSid.
Filtering by tag
Repeattags once per tag. A call matches if it has any of them:
curl "https://api-eg.olimi.ai/api/v2/calls?tags=interested&tags=callback" \
-H "X-API-KEY: YOUR_API_KEY"
tags twice: ?tags=interested&tags=interested. A lone ?tags=interested is rejected with 422, and ?tags[]=interested is ignored.422 validation error:
statusorcallTypeisn’t one of the listed values.agentIdordidNumberIdisn’t a valid UUID.createdFromorcreatedToisn’t an ISO 8601 date.durationFromordurationTois negative or not a number.tagswas sent only once.
campaignId that’s neither a valid UUID nor the word null returns 400 failed_update_data instead.Authorizations
Query Parameters
Page number, starting at 1.
x >= 1Calls per page.
x >= 1Finds calls by contact name, phone number, account code or call reference. See How search works.
Only calls with this status.
pending, in_progress, answered, not_answered, failed Only calls of this type.
inbound, outbound, web Only calls made or answered by this agent.
Only calls from this campaign. Send the word null for calls that aren't part of any campaign. Anything else that isn't a valid UUID returns 400 failed_update_data.
Only calls on this phone number of yours.
Only calls with this account code from your phone system. Exact match.
Only calls with any of these tags. Repeat the parameter for each tag, and repeat it even for one tag. See Filtering by tag.
true returns only calls whose contact came from your website widget, including follow-up calls to them. false isn't a reliable "everything else" filter, because it also drops calls whose contact has no widget flag; filter by callType instead.
Only calls created at or after this time (ISO 8601).
Only calls created at or before this time (ISO 8601).
Only calls at least this many seconds long.
x >= 0Only calls at most this many seconds long.
x >= 0