PHP SDK
The official Odento PHP SDK provides a type-safe interface to the Odento API. PSR-18 compatible HTTP client. Requires PHP 8.0 or later. Available on Packagist.
Installation
Requestbash
composer require odento/sdk
# or manually add to composer.json
{
"require": {
"odento/sdk": "^1.0"
}
}Initialization
Create a client instance with your API key credentials. Load keys from environment variables — never hardcode them in your source:
Requestphp
use Odento\SDK\OdentoClient;
$client = new OdentoClient([
'key_id' => getenv('ODENTO_API_KEY_ID'), // ok_live_...
'key_secret' => getenv('ODENTO_API_KEY_SECRET'), // os_...
]);
// With custom options
$stagingClient = new OdentoClient([
'key_id' => getenv('ODENTO_API_KEY_ID'),
'key_secret' => getenv('ODENTO_API_KEY_SECRET'),
'base_url' => 'https://staging-api.odento.app',
'timeout' => 60,
'max_retries' => 5,
]);JWT Authentication
For user-facing applications, authenticate with email and password. The SDK automatically manages token storage and refresh:
Requestphp
use Odento\SDK\OdentoClient;
$client = new OdentoClient();
// Login — SDK stores tokens internally
$auth = $client->auth()->login([
'email' => 'dr.sharma@dentalkare.in',
'password' => 'your-secure-password',
]);
echo "Logged in as: " . $auth->user->name . "\n";
// All subsequent calls use the stored access token
// The SDK automatically refreshes when the token expiresUsage Examples
List Patients
Requestphp
$result = $client->patients()->list([
'limit' => 10,
'status' => 'active',
]);
foreach ($result->items as $patient) {
echo $patient->id . ': ' . $patient->first_name . ' ' . $patient->last_name . "\n";
}
echo "Has more: " . ($result->pagination->has_more ? 'true' : 'false') . "\n";
// Iterate through all pages
$cursor = $result->pagination->next_cursor;
while ($result->pagination->has_more) {
$result = $client->patients()->list(['limit' => 10, 'cursor' => $cursor]);
foreach ($result->items as $patient) {
echo $patient->id . ': ' . $patient->first_name . "\n";
}
$cursor = $result->pagination->next_cursor;
}Create a Patient
Requestphp
$patient = $client->patients()->create([
'first_name' => 'Priya',
'last_name' => 'Sharma',
'email' => 'priya.sharma@example.com',
'phone' => '+919876543210',
'date_of_birth' => '1990-05-15',
'gender' => 'female',
'address' => [
'street' => '12 MG Road',
'city' => 'Bengaluru',
'state' => 'Karnataka',
'postal_code' => '560001',
'country' => 'India',
],
]);
echo "Created patient: " . $patient->id . "\n"; // pat_5f8d3a2b1c9e4a7bCreate an Appointment
Requestphp
$appointment = $client->appointments()->create([
'patient_id' => 'pat_5f8d3a2b1c9e4a7b',
'dentist_id' => 'usr_abc123',
'start_time' => '2025-01-22T10:00:00Z',
'end_time' => '2025-01-22T11:00:00Z',
'type' => 'consultation',
'location_id' => 'loc_xyz789',
'notes' => 'Routine checkup',
]);
echo "Created appointment: " . $appointment->id . "\n"; // apt_7a3b9c1d2e5f8a4bCreate an Invoice
Requestphp
$invoice = $client->billing()->invoices()->create([
'patient_id' => 'pat_5f8d3a2b1c9e4a7b',
'items' => [
['description' => 'Dental consultation', 'quantity' => 1, 'unit_price' => 50000],
['description' => 'Scaling and polishing', 'quantity' => 1, 'unit_price' => 150000],
],
'due_date' => '2025-02-01',
]);
echo "Created invoice: {$invoice->id} ({$invoice->number}) total: {$invoice->total}\n";
// Created invoice: inv_4a7b9c1d2e5f8a3b (INV-2025-0042) total: 236000Record a Payment
Requestphp
$payment = $client->billing()->invoices()->recordPayment('inv_4a7b9c1d2e5f8a3b', [
'amount' => 59000, // in paise
'method' => 'upi',
'reference' => 'UPI-987654321',
]);
echo "Payment recorded: {$payment->id}\n";
echo "Invoice status: {$payment->invoice_status}\n"; // paidError Handling
The SDK throws typed exceptions. Catch specific exception types to handle different error cases:
Requestphp
use Odento\SDK\Exceptions\OdentoException;
use Odento\SDK\Exceptions\ValidationException;
use Odento\SDK\Exceptions\RateLimitException;
try {
$patient = $client->patients()->create([
'first_name' => 'Priya',
// missing required fields...
]);
} catch (ValidationException $e) {
echo "Validation failed: " . $e->getMessage() . "\n";
foreach ($e->getDetails() as $detail) {
echo " {$detail->field}: {$detail->message}\n";
}
} catch (RateLimitException $e) {
echo "Rate limited. Retry after {$e->retryAfter}s\n";
} catch (OdentoException $e) {
echo "API error ({$e->getCode()}): {$e->getMessage()}\n";
}Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
| key_id | string | — | API key ID (ok_live_*) |
| key_secret | string | — | API key secret (os_*) |
| base_url | string | api.odento.app | Base URL for API requests |
| timeout | int | 30 | Request timeout in seconds |
| max_retries | int | 3 | Max retries for 5xx and 429 errors |
| auto_refresh | bool | true | Auto-refresh JWT tokens before expiry |
Laravel Integration
For Laravel applications, register the SDK as a singleton in your service provider:
Requestphp
// app/Providers/AppServiceProvider.php
use Odento\SDK\OdentoClient;
public function register()
{
$this->app->singleton(OdentoClient::class, function ($app) {
return new OdentoClient([
'key_id' => config('services.odento.key_id'),
'key_secret' => config('services.odento.key_secret'),
]);
});
}
// config/services.php
'odento' => [
'key_id' => env('ODENTO_API_KEY_ID'),
'key_secret' => env('ODENTO_API_KEY_SECRET'),
],Then inject the client in your controllers:
Requestphp
use Odento\SDK\OdentoClient;
class PatientController extends Controller
{
public function __construct(private OdentoClient $odento) {}
public function index()
{
$result = $this->odento->patients()->list(['limit' => 20]);
return response()->json($result);
}
}Was this page helpful?
Help us improve our documentation