{"id":15068606,"url":"https://github.com/artnum/bizcuit-bexio","last_synced_at":"2026-02-20T23:39:30.848Z","repository":{"id":121157227,"uuid":"591256010","full_name":"artnum/BizCuit-Bexio","owner":"artnum","description":"PHP API to access Bexio.com, support API version 2, 3 and 4.","archived":false,"fork":false,"pushed_at":"2025-04-08T09:55:29.000Z","size":486,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-07T02:43:34.356Z","etag":null,"topics":["bexio","bexioapi","cache","cache-storage","curl","curl-library","curlphp","php8","winbiz"],"latest_commit_sha":null,"homepage":"https://bizcuit.ch","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/artnum.png","metadata":{"files":{"readme":"README.en.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-20T10:02:17.000Z","updated_at":"2025-04-08T09:55:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"8f6e6ee2-69ba-41fb-8008-13aa05f2ff6e","html_url":"https://github.com/artnum/BizCuit-Bexio","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/artnum/BizCuit-Bexio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2FBizCuit-Bexio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2FBizCuit-Bexio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2FBizCuit-Bexio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2FBizCuit-Bexio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artnum","download_url":"https://codeload.github.com/artnum/BizCuit-Bexio/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artnum%2FBizCuit-Bexio/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265120110,"owners_count":23714488,"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":["bexio","bexioapi","cache","cache-storage","curl","curl-library","curlphp","php8","winbiz"],"created_at":"2024-09-25T01:38:29.505Z","updated_at":"2026-02-20T23:39:30.819Z","avatar_url":"https://github.com/artnum.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BizCuit-Bexio, bexio API in PHP\n\nIf you are looking to move away from [Bexio](https://bexio.com), there is\nanother project [bx-sync](https://github.com/artnum/bx-sync) which aims to \ndo just that.\n\nThis library allow to access [Bexio API](https://docs.bexio.com/). Constructed\narround cURL, it uses token authentication and provide a great deal of features.\n\nIt abastracts between the differents API version (like 4 in 4 years is quite\na lot) to make every endpoint look the same. It relies on class composition to\nachieve that, example :\n\n```php\nclass BexioContact extends BexioAPI {\n\tprotected $type = 'contact';\n\tprotected $class = 'BizCuit\\BXObject\\Contact';\n\tprotected $query = 'BizCuit\\BXQuery\\Contact';\n\n\n\tuse tBexioV2Api, tBexioObject, tBexioCollection;\n}\n```\n\nStill in active developpement, it also provide tooling to build a data cache\nshort term (to mitigate [Rate Limiting](https://docs.bexio.com/#section/API-basics/Rate-Limiting))\nand long term to keep working (read-only) if the upstream service goes down.\n\n## Endorsement\n\nThe fact that I am developping this doesn't mean that I endorse Bexio product. \nI do it because I need it, but if I were to have the choice, I wouldn't use bexio.\nThe support is quite arrogant and try as hard as possible to drive away dev like\nme, the application is soooooo slow (to get ONE item through the API, you wait\n500ms, even from the official frontend you spend more time waiting than \nworking) and it is expensive.\n\n## Install\n\nVia composer `composer require \"artnum/bizcuit-bexio @dev\"`\n\n## Documentation\n\nDocumentation available at [https://bizcuit.ch](https://bizcuit.ch/bexio/documentation/)\n\n## Example of usage\n\n```php\n\n$context = new BizCuit\\BexioCTX($bexio_api_token);\n\n$bills = new BizCuit\\BexioBills($context);\n$files = new BizCuit\\BexioFile($context);\n\n$billQuery = $bills-\u003enewQuery();\n$billQuery-\u003eadd('status', 'DRAFT');\n\n$billInDraft = $bills-\u003esearch($billQuery);\nforeach($billInDraft as $bill) {\n    foreach($bill-\u003eattachment_ids as $fileUUID) {\n        $fileWithContent = $file-\u003eget($fileUUID);\n    }\n}\n```\n\n## Available Classes\n\nEach class represents an endpoint, adding more classes is quite easy, I just \ndidn't take the time and will add them as I use them.\n\n - BexioCountry\n - BexioQuote\n - BexioInvoice\n - BexioOrder\n - BexioContact\n - BexioProject\n - BexioContactRelation\n - BexioAdditionalAddress\n - BexioNote\n - BexioUser\n - BexioBusinessActivity\n - BexioSalutation\n - BexioTitle\n - BexioProjectType\n - BexioProjectStatus\n - BexioBills\n - BexioFile\n\n## Create new class for endpoint\n\nTo add a read-only class, you can define it with ROObject like, for example,\nBexioProjectStatus :\n\n```php\nclass BexioProjectStatus extends BexioAPI {\n\tprotected $type = 'pr_project_state';\n\tprotected $class = 'BizCuit\\BXObject\\ROObject';\n\tprotected $query = 'BizCuit\\BXQuery\\ROObject';\n\n\tuse tBexioV2Api, tBexioObject, tBexioCollection;\n}\n```\nIn order to create a full class, you would need to define an object class and \na query class (but you can still have a query class ROObject with an object \nclass of the full type), like BexioContact (choosen because this hits a bug in\nthe API and, as the last phone call I had with the company : \"the API is not\nstrategic\", meaning that they don't really care about that).\n\n```php\n/* file bxobject.php */\nclass Contact extends BXObject {\n    const NR = null;\n    const createProperties = [\n        'nr',\n        'contact_type_id',\n        'name_1',\n        'name_2',\n        'salutation_id',\n        'salutation_form',\n        'titel_id',\n        'birthday',\n        'address',\n        'postcode',\n        'city',\n        'country_id',\n        'mail',\n        'mail_second',\n        'phone_fixed',\n        'phone_fixed_second',\n        'phone_mobile',\n        'fax',\n        'url',\n        'skype_name',\n        'remarks',\n        'language_id',\n        'contact_group_ids',\n        'contact_branch_ids',\n        'user_id',\n        'owner_id'\n    ];\n\n    /* API BUG when requesting a contact, if no salutation are set, the result\n     * will have salutation_id = 0, but when sending back to update, edit or\n     * replace the contact, the server complains with this value not being to\n     * \"null\", so this is to fix that.\n     */\n    const nullableProperties = [\n        'salutation_id'\n    ];\n}\n\n/* file bxquery.php */\nclass Contact extends BXQuery {\n\tfunction __construct() {\n\t\tparent::__construct([\n\t\t\t'id',\n\t\t\t'name_1',\n\t\t\t'name_2',\n\t\t\t'nr',\n\t\t\t'address',\n\t\t\t'mail',\n\t\t\t'mail_second',\n\t\t\t'postcode',\n\t\t\t'city',\n\t\t\t'country_id',\n\t\t\t'contact_group_ids',\n\t\t\t'contact_type_id',\n\t\t\t'updated_at',\n\t\t\t'user_id',\n\t\t\t'phone_fixed',\n\t\t\t'phone_mobile',\n\t\t\t'fax'\n\t\t]);\n\t}\n}\n\n/* file bexio.php */\nclass BexioContact extends BexioAPI {\n\tprotected $type = 'contact';\n\tprotected $class = 'BizCuit\\BXObject\\Contact';\n\tprotected $query = 'BizCuit\\BXQuery\\Contact';\n\n\n\tuse tBexioV2Api, tBexioObject, tBexioCollection;\n}\n```\n\n## Available trait for class composition\n\n### tBexioObject\n\n - function new ():BXObject (create a new object of this type)\n - function delete(Int|String|BXObject $id): Bool (delete object)\n - function get (Int|String|BXObject $id, array $options = []):BXObject (get the object)\n - function set (BXObject $content):BXObject|false (save an object)\n - function update (BXObject $content):BXObject|false (update an object)\n\n### tBexioCollection \n \n - function getIdName ():string (get the name of the property used as id for this collection)\n - function newQuery ():BXquery (prepare a query object for this collection)\n - function search (BXQuery $query, Int $offset = 0, Int $limit = 500):array (execute a search on the collection)\n - function list (Int $offset = 0, Int $limit = 500):array (list collection)\n\n### tBexioV2Api, tBexioV3Api and tBexioV4Api\n\nUsed only to set the right API number\n\n### tBexioArchiveable\n - function archive (BXObject $content):bool (archive an object)\n - function unarchive (BXObject $content):bool (unarchive an object)\n\n### tBexioNumberObject\n - function getByNumber (Int|String $id):BXObject (get an object by its number instead of id)\n\n### tBexioPDFObject\n - \tfunction getPDF(Int|BXObject $id):BXObject (get a PDF of the object)\n\n### tBexioProjectObject\n - function listByProject (Int|BXObject $projectId): Array (List by project id)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartnum%2Fbizcuit-bexio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartnum%2Fbizcuit-bexio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartnum%2Fbizcuit-bexio/lists"}