{"id":20941077,"url":"https://github.com/lmc-eu/matej-client-php","last_synced_at":"2025-05-13T23:31:01.437Z","repository":{"id":26419738,"uuid":"108859964","full_name":"lmc-eu/matej-client-php","owner":"lmc-eu","description":"PHP API Client for Matej recommendation engine","archived":false,"fork":false,"pushed_at":"2024-01-18T12:40:34.000Z","size":464,"stargazers_count":11,"open_issues_count":2,"forks_count":7,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-04-15T18:17:50.177Z","etag":null,"topics":["api-client","php","psr-7"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lmc-eu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-10-30T14:11:02.000Z","updated_at":"2023-11-14T15:56:30.000Z","dependencies_parsed_at":"2024-01-18T11:03:26.659Z","dependency_job_id":null,"html_url":"https://github.com/lmc-eu/matej-client-php","commit_stats":{"total_commits":220,"total_committers":10,"mean_commits":22.0,"dds":0.25,"last_synced_commit":"0b55739074c61b3270f201a150500e264623faab"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lmc-eu%2Fmatej-client-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lmc-eu%2Fmatej-client-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lmc-eu%2Fmatej-client-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lmc-eu%2Fmatej-client-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lmc-eu","download_url":"https://codeload.github.com/lmc-eu/matej-client-php/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254043216,"owners_count":22004912,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","php","psr-7"],"created_at":"2024-11-18T23:12:52.556Z","updated_at":"2025-05-13T23:31:00.904Z","avatar_url":"https://github.com/lmc-eu.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PHP API Client for Matej recommendation engine\n\n[![Latest Stable Version](https://img.shields.io/packagist/v/lmc/matej-client.svg?style=flat-square)](https://packagist.org/packages/lmc/matej-client)\n![Required PHP version](https://img.shields.io/packagist/dependency-v/lmc/matej-client/php?style=flat-square)\n[![GitHub Actions Build Status](https://img.shields.io/github/actions/workflow/status/lmc-eu/matej-client-php/php.yaml?style=flat-square\u0026label=GitHub%20Actions%20build)](https://github.com/lmc-eu/matej-client-php/actions)\n[![Coverage Status](https://img.shields.io/coveralls/lmc-eu/matej-client-php/main.svg?style=flat-square)](https://coveralls.io/r/lmc-eu/matej-client-php?branch=main)\n\n## Installation\n\nMatej API client library is installed using [Composer](https://getcomposer.org/).\n**Please be aware you must properly set-up [autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading) in your project first.**\n\nWe use [HTTPlug](https://github.com/php-http/httplug) abstraction so that the library is not hard coupled to\nany specific HTTP library, allowing you to use HTTP library which fits your needs (or maybe HTTP library you already use).\n\nThis means that besides the `lmc/matej-client` library itself you must install a package which provides\n`php-http/client-implementation` - see [list of supported clients and adapters](http://docs.php-http.org/en/latest/clients.html).\n\nIf you, for example, want to use Guzzle 6 as the underlying HTTP library, install the package like this:\n\n```sh\n$ composer require lmc/matej-client php-http/guzzle6-adapter\n```\n\nOr if you want to use Guzzle 5 (note that unlike `guzzle6-adapter`, the one does not come with `guzzlehttp/psr7`, so you must install it as well):\n\n```sh\n$ composer require lmc/matej-client php-http/guzzle5-adapter guzzlehttp/psr7\n```\n\nOr if you want to use cURL client:\n\n```sh\n$ composer require lmc/matej-client php-http/curl-client guzzlehttp/psr7\n```\n\n## Usage\n\nTo start using Matej you will need your account id (database name) and secret API key - both of them must be obtained from LMC R\u0026D team.\n\nFirst create an instance of `Matej` object:\n```php\nuse Lmc\\Matej\\Matej; // in all following examples namespaces and use statements are ommited from the code samples\n\n$matej = new Matej('accountId', 'apikey');\n```\n\nNow you can use `request()` method to use *builders*, which are available for each Matej endpoint and which will\nhelp you to assemble the request. Each request builder accepts via its methods instances of various Command(s)\nobjects (see `Lmc\\Matej\\Model\\Command` namespace). Refer to Matej documentation, code-completion in your IDE or examples\nbelow for more information.\n\nOnce finished with building the request, use `send()` method to execute it and retrieve the response:\n\n```php\n$response = $matej-\u003erequest()\n    -\u003eevents()\n    -\u003eaddInteraction(\\Lmc\\Matej\\Model\\Command\\Interaction::withItem('purchases', 'user-id', 'item-id'))\n    -\u003eaddUserMerge(...)\n    ...\n    -\u003esend();\n```\n\nSee further below for examples of building request for each endpoint.\n\n### Processing the response\n\nOnce `$response` is filled with data from Matej (as in example above), you can now work with the response like this:\n\n```php\necho 'Number of commands: ' . $response-\u003egetNumberOfCommands() . \"\\n\";\necho 'Number of successful commands: ' . $response-\u003egetNumberOfSuccessfulCommands() . \"\\n\";\necho 'Number of failed commands: ' . $response-\u003egetNumberOfFailedCommands()() . \"\\n\";\n\n// Use $response-\u003eisSuccessful() to check whether all of the commands send in request were successful or not:\nif (!$response-\u003eisSuccessful()) {\n    echo 'At least one command response was not succesful!';\n}\n\n// Iterate over getCommandResponses() to get response for each command passed to the builder.\n// Commands in the response are present in the same order as they were added to the requets builder.\nforeach ($response-\u003egetCommandResponses() as $commandResponse) {\n    if ($commandResponse-\u003eisSuccessful()) {\n        // Methods $commandResponse-\u003egetData(), -\u003egetMessage() and -\u003egetStatus() are available\n    } else {\n        // Log error etc.\n    }\n}\n```\n\n[Recommendation](#recommendations-for-single-user), [Sorting](#request-item-sorting-for-single-user)\nand [Item Properties](#item-properties-setup-to-setup-your-matejs-database) endpoints have syntax sugar shortcuts,\nwhich makes processing responses easier. See below for detailed examples.\n\n### Item properties setup (to setup your Matej's database)\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\n// Create new item property in database:\n$response = $matej-\u003erequest()\n    -\u003esetupItemProperties()\n    -\u003eaddProperty(ItemPropertySetup::timestamp('valid_to'))\n    -\u003eaddProperty(ItemPropertySetup::string('title'))\n    -\u003esend();\n\n// Get list of item properties that are defined in Matej\n$response = $matej-\u003erequest()\n    -\u003egetItemProperties()\n    -\u003esend();\n\n$properties = $response-\u003egetData(); // this is shortcut for $response-\u003egetCommandResponse(0)-\u003egetData()\n\n// Delete item property from database:\n$response = $matej-\u003erequest()\n    -\u003edeleteItemProperties()\n    -\u003eaddProperty(ItemPropertySetup::timestamp('valid_from'))\n    -\u003eaddProperty(ItemPropertySetup::string('title'))\n    -\u003esend();\n```\n\n### Reset database\n\nDatabase of test accounts (those ending with `-test`) could be reset via the API.\nUsing this you can delete all data including database setup (item properties).\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\n$response = $matej-\u003erequest()\n    -\u003eresetDatabase()\n    -\u003esend();\n\nvar_dump($response-\u003eisSuccessful()); // true on success\n```\n\n### Reset data\n\nData (users and items) of test accounts (those ending with `-test`) could be reset via the API.\nUsing this you can delete all data while keeping database setup (item properties, scenarios).\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\n$response = $matej-\u003erequest()\n    -\u003eresetData()\n    -\u003esend();\n\nvar_dump($response-\u003eisSuccessful()); // true on success\n```\n\n### Send Events data to Matej\n\nYou can use `events()` builder for sending batch of following commands to Matej:\n- `Interaction` via `addInteraction()` - to send information about interaction between user and item\n- `ItemProperty` via `addItemProperty()` - to update item data stored in Matej database\n- `UserMerge` via `addUserMerge()` - to merge interactions of two users and delete the source user\n\nYou can mix different command types in the same request. You can send up to 1 000 commands in a single request.\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\n$response = $matej-\u003erequest()\n    -\u003eevents()\n    // Add interaction between user and item\n    -\u003eaddInteraction(Interaction::withItem('purchases', 'user-id', 'item-id'))\n    -\u003eaddInteractions([/* array of Interaction objects */])\n    // Update item data\n    -\u003eaddItemProperty(ItemProperty::create('item-id', ['valid_from' =\u003e time(), 'title' =\u003e 'Title']))\n    -\u003eaddItemProperties([/* array of ItemProperty objects */])\n    // Merge user\n    -\u003eaddUserMerge(UserMerge::mergeInto('target-user-id', 'source-user-id', 1629361884))\n    -\u003eaddUserMerges([/* array of UserMerge objects */])\n    -\u003esend();\n```\n\n**This endpoint has rate-limiting implemented.** We constantly monitor workload on backend systems,\nand when the number of events in the queue crosses certain threshold, Matej API will start returning `429` errors.\nIf that happens, you should resend the entire request later, as no commands were processed.\n\nThis has been implemented so that we don't lose any pushed data. Simple sleep of 100ms should be enough.\n\n### Merging users\n\nYou can merge users using the `UserMerge` command. The first argument is the target user ID and the second argument is the ID\nof source user. When you merge two users, Matej will move all interactions and history of the source user and assign them to\nthe target user. The source user is then removed.\n\nOptionally, you may send a third argument with a timestamp of when the merge happened.\n\n**The timestamp will be required in the future. We reccommend you to send it which will make future upgrades of the Matej client easier for you.**\n\n### Requesting recommendations\n\nYou can request 4 types of recommendations from Matej. Each of them is represented by a specific recommendation command class:\n\n- Items to user - UserItemRecommendation\n- Items to item - ItemItemRecommendation\n- Users to user - UserUserRecommendation\n- Users to item - ItemUserRecommendation\n\nFor example, you can get recommendations for a single user using `recommendation()` builder.\nYou can attach most recent interaction and user merge event to the request so that they're taken into account\nwhen providing recommendations.\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\n$response = $matej-\u003erequest()\n    -\u003erecommendation(UserItemRecommendation::create('user-id', 'test-scenario'))\n    -\u003esetInteraction(Interaction::withItem('purchases', 'user-id', 'item-id')) // optional\n    -\u003esetUserMerge(UserMerge::mergeInto('user-id', 'source-id')) // optional\n    -\u003esend();\n\n$recommendations = $response-\u003egetRecommendation()-\u003egetData();\n```\n\nYou can also set more granular options of the recommendation command and overwrite Matej default behavior on per-request basis.\n\nEach type of recommendation command supports different customization options. See table below.\n\n\n#### Available recommendation attributes\n\n| Attribute      | Methods                                   | UserItemRecommendation | UserUserRecommendation | ItemItemRecommendation | ItemUserRecommendation |\n|---------------|-------------------------------------------|------------------------|------------------------|------------------------|------------------------|\n| scenario      |              in constructor               |            ✅           |            ✅           |            ✅           |            ✅           |\n| count         |                  `setCount`                 |            ✅           |            ✅           |            ✅           |            ✅           |\n| rotation_rate |              `setRotationRate`              |            ✅           |            ✅           |            ❌           |            ❌           |\n| rotation_time |              `setRotationTime`              |            ✅           |            ✅           |            ❌           |            ❌           |\n| hard_rotation |             `enableHardRotation`            |            ✅           |            ✅           |            ❌           |            ❌           |\n| allow_seen    |                `setAllowSeen`               |            ✅           |            ❌           |            ❌           |            ✅           |\n| min_relevance |            `setMinimalRelevance`            |  `ItemMinimalRelevance`  |            ❌           |            ❌           |  `UserMinimalRelevance`  |\n| filter        |            `addFilter` `setFilters`           |            ✅           |            ❌           |            ✅           |            ❌           |\n| boost_rules   |             `addBoost` `setBoosts`            |            ✅           |            ❌           |            ✅           |            ❌           |\n| model_name    |                `setModelName`               |            ✅           |            ✅           |            ✅           |            ✅           |\n| properties    | `addResponseProperty` `setResponseProperties` |            ✅           |            ❌           |            ✅           |            ❌           |\n\n\n```php\n$recommendation = UserItemRecommendation::create('user-id', 'test-scenario')\n    -\u003esetCount(5)\n    -\u003esetRotationRate(1.0)\n    -\u003esetRotationTime(3600)\n    -\u003esetFilters(['for_recommendation = 1'])\n    -\u003esetMinimalRelevance(ItemMinimalRelevance::HIGH())\n    -\u003eenableHardRotation()\n    // You can further modify which items will be recommended by providing boosting rules.\n    // Priority of items matching the query will be multiplied by the value of multiplier:\n    -\u003eaddBoost(Boost::create('valid_to \u003e= NOW()', 2));\n\n$response = $matej-\u003erequest()\n    -\u003erecommendation($recommendation)\n    -\u003esend();\n```\n\nFrom `$response`, you can also access rest of the data:\n\n```php\n$response = $matej-\u003erequest()\n    -\u003erecommendation($recommendation)\n    -\u003esend();\n\necho $response-\u003egetInteraction()-\u003egetStatus();    // SKIPPED\necho $response-\u003egetUserMerge()-\u003egetStatus();      // SKIPPED\necho $response-\u003egetRecommendation()-\u003egetStatus(); // OK\n\n$recommendations = $response-\u003egetRecommendation()-\u003egetData();\n\n// var_dump($recommendations):\n// array(2) {\n//     [0] =\u003e object(stdClass)#1 (2) {\n//         [\"item_id\"]  =\u003e string(9) \"item_id_1\"\n//     }\n//     [1] =\u003e object(stdClass)#2 (2) {\n//         [\"item_id\"]  =\u003e string(9)  \"item_id_2\"\n//     }\n// }\n```\n\n#### Recommendation response properties\n\nEvery item in Matej has its id, and optionally other item properties. These properties can be set up in [item properties setup](#item-properties-setup-to-setup-you-matej-database),\nand you can upload item data in the [events](#send-events-data-to-matej) request. This has major benefit because you can request\nthese properties to be returned as part of your Recommendation Request.\n\nWe call them response properties. They can be specified by calling `-\u003eaddResponseProperty()` method or by calling `-\u003esetResponseProperties()` method. Following will request an `item_id`, `item_url`, `item_title`:\n\n```php\n$recommendation = UserItemRecommendation::create('user-id', 'test-scenario')\n    -\u003eaddResponseProperty('item_title')\n    -\u003eaddResponseProperty('item_url');\n\n$response = $matej-\u003erequest()\n    -\u003erecommendation($recommendation)\n    -\u003esend();\n\n$recommendedItems = $response-\u003egetRecommendation()-\u003egetData();\n\n// $recommendedItems is an array of stdClass instances:\n//\n// array(2) {\n//     [0] =\u003e object(stdClass)#1 (2) {\n//         [\"item_id\"]  =\u003e string(9) \"item_id_1\"\n//         [\"item_url\"] =\u003e string(5) \"url_1\"\n//         [\"item_title\"] =\u003e string(5) \"title_1\"\n//     }\n//     [1] =\u003e object(stdClass)#2 (2) {\n//         [\"item_id\"]  =\u003e string(9)  \"item_id_2\"\n//         [\"item_url\"] =\u003e string(10) \"url_2\"\n//         [\"item_title\"] =\u003e string(10) \"title_2\"\n//     }\n// }\n```\n\nIf you don't specify any response properties, Matej will return an array of `stdClass` instances, which contain only `item_id` property.\nIf you do request at least one response property, you don't need to mention `item_id`, as Matej will always return it regardless of the\nproperties requested.\n\nIf you request an unknown property, Matej will return a `BAD REQUEST` with HTTP status code `400`.\n\nThis way, when you receive recommendations from Matej, you don't need to loop the `item_id` and retrieve further information\nfrom your local database. It means, however, that you'll have to keep all items up to date within Matej,\nwhich can be done through [events](#send-events-data-to-matej) request.\n\n### Request item sorting for single user\n\nRequest item sorting for a single user. You can combine this sorting command with the most recent interaction\nand user merge event in one request, to make them taken into account when executing the item sorting.\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\n$response =  $matej-\u003erequest()\n    -\u003esorting(ItemSorting::create('user-id', ['item-id-1', 'item-id-2', 'item-id-3']))\n    -\u003esetInteraction(Interaction::withItem('purchases', 'user-id', 'item-id')) // optional\n    -\u003esetUserMerge(UserMerge::mergeInto('user-id', 'source-id')) // optional\n    -\u003esend();\n\n$sortedItems = $response-\u003egetSorting()-\u003egetData();\n```\n\nFrom `$response`, you can also access rest of the data:\n\n```php\n$response = $matej-\u003erequest()\n    -\u003esorting($sorting)\n    -\u003esend();\n\necho $response-\u003egetInteraction()-\u003egetStatus(); // SKIPPED\necho $response-\u003egetUserMerge()-\u003egetStatus();   // SKIPPED\necho $response-\u003egetSorting()-\u003egetStatus();     // OK\n\n$sortedData = $response-\u003egetSorting()-\u003egetData();\n```\n\n### Request batch of recommendations/item sortings\n\nUse `campaign()` builder to request batch of recommendations and/or item sorting for multiple users.\nA typical use case for this is generating email campaigns.\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\n$response = $matej-\u003erequest()\n    -\u003ecampaign()\n    // Request item sortings\n    -\u003eaddSorting(ItemSorting::create('user-id', ['item-id-1', 'item-id-2', 'item-id-3']))\n    -\u003eaddSortings([/* array of Sorting objects */])\n    // Request user-based recommendations\n    -\u003eaddRecommendation(UserItemRecommendation::create('user-id', 'emailing'))\n    -\u003eaddRecommendations([/* array of UserRecommendation objects */])\n    -\u003esend();\n```\n\n### A/B Testing support\n`Recommendation` and `ItemSorting` commands support optional A/B testing of various models. This has to be set up in Matej first,\nbut once available, you can specify which model you want to use when requesting recommendations or sorting.\n\nThis is available for `Recommendation`, `ItemSorting` and `Campaign` requests:\n\n```php\n$recommendationCommand = UserItemRecommendation::create('user-id', 'test-scenario')\n    -\u003esetModelName('alpha');\n\n$sortingCommand = ItemSorting::create('user-id', ['item-id-1', 'item-id-2', 'item-id-3']);\n$sortingCommand-\u003esetModelName('beta');\n\n$response = $matej-\u003erequest()\n    -\u003erecommendation($recommendationCommand)\n    -\u003esend();\n\n$response = $matej-\u003erequest()\n    -\u003esorting($sortingCommand)\n    -\u003esend();\n\n$response = $matej-\u003erequest()\n    -\u003ecampaign()\n    -\u003eaddRecommendation($recommendationCommand-\u003esetModelName('gamma'))\n    -\u003eaddSorting($sortingCommand-\u003esetModelName('delta'))\n    -\u003esend();\n```\n\nIf you don't provide any model name, the request will be sent without it, and Matej will use default model for your instance.\n\nTypically, you'd select a random sample of users, to which you'd present recommendations and sorting from second model. This way, implementation\nin your code should look similar to this:\n\n```php\n$recommendation = UserItemRecommendation::create('user-id', 'test-scenario');\n\nif ($session-\u003eisUserInBucketB()) {\n    $recommendation-\u003esetModelName('alpha');\n}\n\n$response = $matej-\u003erequest()-\u003erecommendation($recommendation)-\u003esend();\n```\n\nModel names will be provided to you by LMC.\n\n### Forgetting user data (GDPR)\nMatej can \"forget\" user data, either by anonymizing or by deleting them. The right to erasure (\"right to be forgotten\") is part of\n[General Data Protection Regulation in the European Union](https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679#d1e2606-1-1)\nand can be implemented on your end using the `forget()` builder.\n\nThere are two ways how to remove user data, but both of them aren't reversible and you will not be able to identify\nthe user ever again:\n\n* Preferred way is to `anonymize` the user, which will randomly generate unique identifiers for all personal data,\n  and change that identifier across all databases and logfiles. This way the users behavior will stay in Matej database,\n  and therefore **will continue to contribute to the recommendation model**, but you won't be able to identify the user.\n  Thus his profile will be effectively frozen (as no new interactions can come in.) **New user id is generated server-side**,\n  so there is no going back after issuing the request.\n* An alternate way is to `delete` the user, which will wipe their data from all databases in accordance\n  with the Data Protection laws. This may affect the quality of recommendations, as the users behavior will be completely\n  removed from all databases, and therefore their profile will not contribute to the recommendation model anymore.\n\nUsually, though, the user will identify whether they want their data anonymized or deleted, and you have to adhere to their request.\n\nTo call the endpoint, use the `forget()` builder and append the users:\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\n$matej-\u003erequest()\n    -\u003eforget()\n    -\u003eaddUser(UserForget::anonymize('anonymize-this-user-id'))\n    -\u003eaddUser(UserForget::anonymize('delete-this-user-id'))\n    -\u003eaddUsers([\n        UserForget::anonymize('anonymize-this-user-id-as-well'),\n        UserForget::delete('delete-this-user-id-as-well'),\n    ])\n    -\u003esend()\n;\n```\n\n### Exceptions and error handling\n\nExceptions are thrown only if the whole Request to Matej failed (when sending, decoding, authenticating etc.) or if\nthe library is used incorrectly. If the request is successfully delivered to Matej, **exception is not thrown** even\nif any (or maybe all) of the submitted commands (which were part of the request) were rejected by Matej.\n\nTo check whether the whole Response (ie. all contained command responses) is successful, you thus MUST NOT rely on exceptions\n(because they won't be thrown - as stated above) but rather use `Response::isSuccessful()` method - see [usage examples](#processing-the-response) above.\n\nIf you want to check which individual CommandResponse was successful, you can check its status using `CommandResponse::isSuccessful()` method.\n\nExceptions occurring inside Matej API client implements `Lmc\\Matej\\Exception\\MatejExceptionInterface`.\nThe exception tree is:\n\n| Exception                                         | Thrown when                                                   |\n|---------------------------------------------------|---------------------------------------------------------------|\n| MatejExceptionInterface                           | Common interface of all Matej exceptions                      |\n| └ RequestException                                | Request to Matej errored (see below for troubleshooting howto)|\n| \u0026nbsp;\u0026nbsp;└ AuthorizationException              | Request errored as unauthorized                               |\n| └ ResponseDecodingException                       | Response contains invalid or inconsistent data                |\n| └ LogicException                                  | Incorrect library use - no data passed to request etc.        |\n| \u0026nbsp;\u0026nbsp;└ DomainException                     | Invalid value was passed to domain model                      |\n\nPlease note if you inject custom HTTP client (via `$matej-\u003esetHttpClient()`), it may be configured to throw custom\nexceptions when HTTP request fails. So please make sure this behavior is disabled (eg. `http_errors` option in Guzzle 6).\n\n#### Troubleshooting `RequestException`\n\nIf `RequestException` is thrown when doing request to Matej, you may want to read the response body from the server\nto see the full error originating from Matej, so that you can troubleshoot the cause of the exception.\n\nYou can do it like this:\n\n```php\n$matej = new Matej('accountId', 'apikey');\n\ntry {\n    $response = $matej\n        -\u003erequest()\n        -\u003esorting(/* ... */)\n        // ...\n        -\u003esend();\n} catch (\\Lmc\\Matej\\Exception\\RequestException $exception) {\n    echo $e-\u003egetMessage(); // this will output just HTTP reason phrase, like \"Bad Request\"\n    $serverResponseContents = $exception-\u003egetResponse()\n        -\u003egetBody()\n        -\u003egetContents();\n\n    echo $serverResponseContents; // this will output the full response body which Matej server gave\n}\n```\n\n## Changelog\nFor latest changes see [CHANGELOG.md](CHANGELOG.md) file. We follow [Semantic Versioning](http://semver.org/).\n\n## Releasing new version\nSee [RELEASE.md](RELEASE.md) for step-by-step how to release new client version.\n\n## Running Tests\n\nFor each pull-request, unit tests, as well as static analysis and codestyle checks, must pass.\n\nTo run all those checks execute:\n\n```sh\n$ composer all\n```\n\nIn case of codestyle violation you can run this command which will try to automatically fix the codestyle:\n\n\n```sh\n$ composer fix\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flmc-eu%2Fmatej-client-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flmc-eu%2Fmatej-client-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flmc-eu%2Fmatej-client-php/lists"}