Search by

noosh24 / open-api

AliverdiSultanli

Official PHP client for the Noosh24 Open API

v0.1.0 2026-11-11 13:55 UTC

This package is auto-updated.

Last update: 2026-11-11 15:05:30 UTC


README

Noosh24

Noosh24 Open API for PHP

The official PHP client for the Noosh24 Open API.
Menu, reservations, orders and bills, payments and the Z-report, tables, customers, loyalty, stock and reviews of a Noosh24 venue, plus creating and cancelling reservations.

CI PHP 8.2+ Packagist MIT license

Developer site · API reference · All SDKs · Report an issue

Important

Keep the API key on your server. A key belongs to one venue and opens its data: guests' phone numbers, payments, and writing reservations. Never put it in a browser, a mobile app or a public repository.

Contents: Requirements · Install · Quick start · Options · Resources · Lists, filters and pages · Reservations · Errors · Retries and rate limits · Development · License

Requirements

  • PHP 8.2 or newer (tested on 8.2, 8.3, 8.4 and 8.5), ext-curl, ext-json. No other dependencies.

Install

composer require noosh24/open-api

Quick start

<?php

require 'vendor/autoload.php';

use Noosh24\OpenApi\Client;
use Noosh24\OpenApi\Where;

$noosh = new Client(getenv('NOOSH24_API_KEY'));

$me = $noosh->whoami();
echo $me->restaurant->name, PHP_EOL;
print_r($me->key->scopes);

$page = $noosh->menu->listProducts([
    'where' => Where::create()->eq('category', 'Salads')->eq('available', true),
    'sort' => 'price desc',
    'limit' => 50,
]);
foreach ($page as $product) {
    printf("%s  %.2f AZN\n", $product->name, $product->price);
}
echo $page->total, ' products match', PHP_EOL;

The key belongs to one venue, so there is no venue parameter anywhere. Keys are issued in the Noosh24 panel; keep them on your server, never in a browser or a mobile app.

Options

$noosh = new Client('nsk_...', [
    'baseUrl' => 'https://open-api.noosh24.com/v1',
    'timeout' => 30,
    'maxRetries' => 2,
    'userAgent' => 'acme-pos/2.1',
]);

timeout is in seconds. transport takes your own Noosh24\OpenApi\Http\Transport if you do not want cURL.

Resources

Group Methods
whoami() the venue, the key's scopes and the venue's modules
menu listCategories(), listProducts(), iterateProducts(), getProduct($id, $expand), getStopList()
reservations list(), iterate(), get($id), availability($date, $time, $guests), create([...]), cancel($id)
orders list(), iterate(), get($id), listBills(), iterateBills(), getBill($id)
payments list(), iterate(), get($id), zReport($date)
tables list(), listHalls()
customers list(), iterate(), get($id)
loyalty getProgram(), listCards(), iterateCards()
stock listIngredients(), iterateIngredients(), listMoves(), iterateMoves(), listStores()
reviews list(), iterate()

Every response is a typed model (Product, Reservation, Order, ...) with public properties named as in the API. Timestamps are DateTimeImmutable in UTC, money is float in AZN. $model->toArray() gives the raw JSON, including fields this version of the SDK does not know yet.

Lists, filters and pages

List methods take limit, offset, sort, where and, for products, expand. They return a Page with items, total, limit, offset and hasMore().

$page = $noosh->orders->list([
    'where' => "status = 'served' AND createdAt >= '2026-11-01'",
    'sort' => ['createdAt desc'],
    'limit' => 100,
    'offset' => 0,
]);

where is AND only. Build it with Where so strings and dates are quoted correctly:

$where = Where::create()
    ->eq('status', 'confirmed')
    ->gte('startsAt', new DateTimeImmutable('2026-11-20T00:00:00+04:00'))
    ->in('zone', ['Terrace', "Chef's table"]);

The iterate*() methods walk every page for you and fetch the next page only when you reach it:

foreach ($noosh->payments->iterate(['where' => "createdAt >= '2026-11-01'"]) as $payment) {
    // ...
}

offset stops at 10000. For bigger exports, narrow where by date and walk one window at a time.

Reservations

use Noosh24\OpenApi\Exception\TableTakenException;

$free = $noosh->reservations->availability('2026-11-20', '19:30', 4);

try {
    $result = $noosh->reservations->create([
        'date' => '2026-11-20',
        'time' => '19:30',
        'guests' => 4,
        'guestName' => 'Aysel Məmmədova',
        'phone' => '+994501234567',
        'tableId' => $free->tables[0]->id,
        'externalRef' => 'acme-booking-991',
    ]);
} catch (TableTakenException $e) {
    // someone took the table first
}

echo $result->reservation->code, $result->created ? ' created' : ' already existed', PHP_EOL;

$noosh->reservations->cancel($result->reservation->id);

A booking lands as pending and the venue confirms it. Always send externalRef (your own booking id): sending the same externalRef again returns the booking that already exists instead of making a second one, so a create is safe to retry. The client retries a create only when it carries an externalRef. You can cancel only bookings your key created.

Errors

Every API error throws a subclass of Noosh24\OpenApi\Exception\ApiException with getStatus(), getErrorCode() (the API's error field), getMessage() and getHeaders(). Branch on the class or on getErrorCode(), not on the message.

error Exception Parent
validation_error ValidationException ApiException
no_api_key NoApiKeyException AuthenticationException
invalid_api_key InvalidApiKeyException AuthenticationException
insufficient_scope InsufficientScopeException PermissionDeniedException
module_not_enabled ModuleNotEnabledException PermissionDeniedException
venue_suspended VenueSuspendedException PermissionDeniedException
not_your_reservation NotYourReservationException PermissionDeniedException
not_found NotFoundException ApiException
table_not_found TableNotFoundException NotFoundException
table_taken TableTakenException ConflictException
cannot_cancel CannotCancelException ConflictException
outside_hours, in_the_past, table_too_small OutsideHoursException, InThePastException, TableTooSmallException UnprocessableException
rate_limit_exceeded RateLimitException (getRetryAfter()) ApiException
temporarily_unavailable TemporarilyUnavailableException ServerException

A network failure or timeout throws ConnectionException. All of them implement Noosh24Exception.

Retries and rate limits

A key gets 600 requests a minute. On 429 and 502/503/504 the client waits (Retry-After when the API sends it, otherwise 0.5 s, 1 s, 2 s ...) and tries again, up to maxRetries times. It never waits more than 60 seconds; a longer Retry-After is thrown to you as a RateLimitException. Reads, cancels and creates with an externalRef are retried; a create without an externalRef is not.

Development

composer install
composer test

License

MIT