PHPackages                             oriacall/sdk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. oriacall/sdk

ActiveLibrary[API Development](/categories/api)

oriacall/sdk
============

PHP SDK for the Oriacall Developer API.

v0.2.1(3w ago)052↓70%MITPHPPHP ^8.2

Since Jun 3Pushed 1w agoCompare

[ Source](https://github.com/Karim-Chrif/oriacall-php-sdk)[ Packagist](https://packagist.org/packages/oriacall/sdk)[ RSS](/packages/oriacall-sdk/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (2)Versions (8)Used By (0)

oriacall/sdk
============

[](#oriacallsdk)

PHP SDK for the Oriacall Developer API.

Install
-------

[](#install)

```
composer require oriacall/sdk
```

Requirements:

- PHP 8.2 or newer.
- PHP `curl` and `json` extensions.
- An Oriacall Developer API client ID and secret.
- Server-side usage only. Do not expose `clientSecret` in browser code.

Quickstart
----------

[](#quickstart)

```
use Oriacall\Oriacall;

$oriacall = Oriacall::client([
    'clientId' => getenv('ORIACALL_CLIENT_ID'),
    'clientSecret' => getenv('ORIACALL_CLIENT_SECRET'),
    'scope' => ['hello:read', 'objectives:read', 'calls:read'],
]);

$hello = $oriacall->hello->get();
echo $hello->data['message'].' '.$hello->requestId.PHP_EOL;

$calls = $oriacall->calls->list(['limit' => 50]);
print_r($calls->data['data']);
```

The SDK requests and caches a short-lived access token using client credentials, then sends it as a bearer token for API calls.

Client Options
--------------

[](#client-options)

```
$oriacall = Oriacall::client([
    'baseUrl' => 'https://api.oriacall.com',
    'clientId' => getenv('ORIACALL_CLIENT_ID'),
    'clientSecret' => getenv('ORIACALL_CLIENT_SECRET'),
    'scope' => ['calls:read'],
    'retries' => 2,
    'retryBaseDelayMs' => 250,
    'retryMaxDelayMs' => 2000,
    'timeoutSeconds' => 30,
    'onResponse' => function (array $event): void {
        error_log(json_encode($event));
    },
]);
```

Options:

OptionTypeRequiredDescription`clientId``string`YesDeveloper API client ID.`clientSecret``string`YesDeveloper API client secret. Keep this server-side.`baseUrl``string`NoAPI base URL. Defaults to `https://api.oriacall.com`.`scope``stringarraynull``onResponse``callablenull`No`retries``int`NoRetry count for token requests and GET endpoints. Defaults to `0`.`retryBaseDelayMs``int`NoInitial retry delay. Defaults to `250`.`retryMaxDelayMs``int`NoMaximum retry delay. Defaults to `2000`.`timeoutSeconds``int`NocURL timeout. Defaults to `30`.Response Envelope
-----------------

[](#response-envelope)

Every endpoint method returns `Oriacall\ApiResponse`:

```
$response->data;      // decoded JSON array, or null for delete responses
$response->status;    // HTTP status code
$response->requestId; // X-Request-Id when provided
```

Methods
-------

[](#methods)

```
$oriacall->getAccessToken();
$oriacall->raw('GET', '/v1/hello');
$oriacall->hello->get();

$oriacall->objectives->list(['limit' => 50]);
$oriacall->objectives->update('objective-id', ['customFields' => ['region' => 'north']]);
$oriacall->objectives->paginate(['limit' => 50]);

$oriacall->objectiveCustomFields->list();
$oriacall->objectiveCustomFields->create(['key' => 'region', 'label' => 'Region', 'type' => 'text']);
$oriacall->objectiveCustomFields->update('region', ['label' => 'Sales Region']);

$oriacall->agents->list(['objectiveId' => 'objective-id']);
$oriacall->agents->paginate(['limit' => 50]);

$oriacall->calls->list(['limit' => 50, 'sortBy' => 'recordedAt']);
$oriacall->calls->get('call-id');
$oriacall->calls->update('call-id', ['recordedAt' => '2026-06-10T14:30:00Z']);
$oriacall->calls->upload([...]);
$oriacall->calls->queueAnalysis('call-id');
$oriacall->calls->waitForAnalysis('call-id', ['timeoutMs' => 120000]);
$oriacall->calls->paginate(['limit' => 50]);

$oriacall->leads->list(['customFields' => ['crm_stage' => 'qualified']]);
$oriacall->leads->get('lead-id');
$oriacall->leads->update('lead-id', ['customFields' => ['crm_stage' => 'won']]);
$oriacall->leads->upsertByExternalId('crm-lead-id', ['firstName' => 'Ada', 'lastName' => 'Lovelace']);
$oriacall->leads->paginate(['limit' => 50]);

$oriacall->leadCustomFields->list();
$oriacall->leadCustomFields->create(['key' => 'crm_stage', 'label' => 'CRM Stage', 'type' => 'text']);
$oriacall->leadCustomFields->update('crm_stage', ['label' => 'CRM Stage']);

$oriacall->webhooks->endpoints->list();
$oriacall->webhooks->endpoints->create(['url' => 'https://example.com/oriacall/webhooks', 'events' => ['analysis.completed']]);
$oriacall->webhooks->endpoints->update('endpoint-id', ['isActive' => false]);
$oriacall->webhooks->endpoints->rotateSecret('endpoint-id');
$oriacall->webhooks->endpoints->test('endpoint-id');
$oriacall->webhooks->endpoints->delete('endpoint-id');
$oriacall->webhooks->endpoints->paginate(['limit' => 50]);
```

`$oriacall->calls->get('call-id')` includes transcript data when available. Transcript turn `speaker` values can be `agent`, `client`, or `system`. `system` represents telephony infrastructure such as voicemail greetings, carrier messages, transfer prompts, or tones; it is not a human participant.

Upload A Call
-------------

[](#upload-a-call)

```
$response = $oriacall->calls->upload([
    'idempotencyKey' => 'crm-call-123',
    'externalId' => 'crm-call-123',
    'recordedAt' => '2026-06-10T14:30:00Z',
    // Optional hint. Oriacall may override it during audio analysis.
    'objectiveId' => 'objective-id',
    'queueAnalysis' => true,
    'agent' => [
        'externalId' => 'agent-1',
        'name' => 'Morgan Agent',
        'email' => 'morgan@example.com',
    ],
    'lead' => [
        'externalId' => 'lead-1',
        'firstName' => 'Ada',
        'lastName' => 'Lovelace',
        'phone' => '+15555550100',
        'customFields' => [
            'crm_stage' => 'qualified',
        ],
    ],
    'audio' => [
        'path' => storage_path('app/calls/call.mp3'),
        'filename' => 'call.mp3',
        'contentType' => 'audio/mpeg',
    ],
]);

echo $response->data['data']['id'];
echo $response->data['data']['recordedAt'];
```

To upload in-memory audio, use `contents` instead of `path`:

```
'audio' => [
    'contents' => $audioBytes,
    'filename' => 'call.mp3',
    'contentType' => 'audio/mpeg',
]
```

Required scope: `calls:write`.

Update original source recording time for an existing call:

```
$response = $oriacall->calls->update('call-id', [
    'recordedAt' => '2026-06-10T14:30:00Z',
]);

echo $response->data['data']['recordedAt'];
```

Required scope: `calls:write`.

`objectiveId` is optional. When provided, Oriacall associates the call with that organization objective. When omitted, Oriacall associates the call with an existing objective in the organization.

Call summaries include `callResult`, `callResultLabel`, and `callQualityScore`. `analysisStatus` is one of `pending`, `queued`, `processing`, `completed`, or `failed`. `queueStatus` is `queued`, `processing`, `completed`, `failed`, or `null` when analysis has not been queued. `analysisStage` is `audio_pass`, `text_pass`, `publishing`, `completed`, or `null` when analysis has not been queued. Internal dead-letter and cancelled runs are exposed as `failed`. Completed call analysis includes `summary`, `callStrengths`, `callWeaknesses`, `callObservations`, `objections`, and `alerts`.

Pagination
----------

[](#pagination)

List endpoints use cursor pagination.

```
$firstPage = $oriacall->calls->list(['limit' => 50]);

if ($cursor = $firstPage->data['pagination']['nextCursor']) {
    $secondPage = $oriacall->calls->list(['limit' => 50, 'cursor' => $cursor]);
}

foreach ($oriacall->calls->paginate(['limit' => 50]) as $call) {
    echo $call['id'].PHP_EOL;
}
```

Pagination helpers are available for `objectives`, `agents`, `calls`, `leads`, and `webhooks->endpoints`.

Custom Field Filters
--------------------

[](#custom-field-filters)

Use SDK option names that match the TypeScript SDK. The PHP SDK maps them to the public API query parameters:

```
$oriacall->objectives->list([
    'objectiveCustomFields' => [
        'region' => 'north',
        'priority' => ['gte' => 5],
    ],
]);

$oriacall->calls->list([
    'recordedAfter' => '2026-01-01T00:00:00Z',
    'recordedBefore' => '2026-02-01T00:00:00Z',
    'sortBy' => 'recordedAt',
    'leadCustomFields' => [
        'crm_stage' => 'qualified',
    ],
]);

$oriacall->leads->list([
    'customFields' => [
        'crm_stage' => 'qualified',
    ],
]);
```

For calls, `createdAfter` and `createdBefore` filter by Oriacall upload/record creation time. Use `recordedAfter`, `recordedBefore`, and `sortBy => recordedAt` for original call chronology. The recorded-time filters and sort fall back to `createdAt` when `recordedAt` is null.

Errors
------

[](#errors)

Failed API calls throw `Oriacall\ApiError`:

```
use Oriacall\ApiError;

try {
    $oriacall->calls->get('call-id');
} catch (ApiError $error) {
    logger()->error('Oriacall failed', [
        'status' => $error->status,
        'code' => $error->errorCode,
        'message' => $error->getMessage(),
        'request_id' => $error->requestId,
        'details' => $error->details,
        'retry_after' => $error->retryAfter,
    ]);
}
```

Webhook Signature Verification
------------------------------

[](#webhook-signature-verification)

```
use Oriacall\Oriacall;

$valid = Oriacall::verifyWebhookSignature(
    body: $request->getContent(),
    secret: config('services.oriacall.webhook_secret'),
    signature: $request->header('Oriacall-Signature'),
    timestamp: $request->header('Oriacall-Timestamp'),
);
```

Scopes
------

[](#scopes)

Available scopes:

```
hello:read
objectives:read
objectives:write
objective_custom_fields:manage
agents:read
calls:read
calls:write
leads:read
leads:write
lead_custom_fields:manage
webhooks:read
webhooks:write

```

The token request can only request scopes that were granted to that API client.

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance97

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

7

Last Release

22d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9c562a4603569bc0e86c661a87dec5a2e5403463fef3a11ccf8d854fc187c4a8?d=identicon)[carim](/maintainers/carim)

---

Top Contributors

[![Karim-Chrif](https://avatars.githubusercontent.com/u/45574750?v=4)](https://github.com/Karim-Chrif "Karim-Chrif (10 commits)")

---

Tags

phpapilaravelsdkoriacall

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/oriacall-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/oriacall-sdk/health.svg)](https://phpackages.com/packages/oriacall-sdk)
```

###  Alternatives

[mozex/anthropic-laravel

Laravel integration for the Anthropic API: facade, config publishing, install command, testing fakes, messages, streaming, tool use, thinking, and batches.

74331.3k1](/packages/mozex-anthropic-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
