PHPackages                             bedita/php-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. bedita/php-sdk

ActiveLibrary[API Development](/categories/api)

bedita/php-sdk
==============

BEdita PHP SDK

v4.2.0(7mo ago)489.4k↑40.3%2[4 issues](https://github.com/bedita/php-sdk/issues)1MITPHPPHP &gt;=8.3CI passing

Since Aug 6Pushed 2mo ago4 watchersCompare

[ Source](https://github.com/bedita/php-sdk)[ Packagist](https://packagist.org/packages/bedita/php-sdk)[ Docs](https://www.bedita.com)[ RSS](/packages/bedita-php-sdk/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (9)Versions (23)Used By (1)

BEdita API PHP SDK
==================

[](#bedita-api-php-sdk)

BEdita PHP Official PHP SDK

[![Github Actions PHP](https://github.com/bedita/php-sdk/workflows/php/badge.svg)](https://github.com/bedita/php-sdk/actions?query=workflow%3Aphp)[![Code Coverage](https://camo.githubusercontent.com/f88abd0d54f5884981edad74795902f435027232ea421ca42886cebbcde7a37a/68747470733a2f2f636f6465636f762e696f2f67682f6265646974612f7068702d73646b2f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/bedita/bedita/branch/master)[![phpstan](https://camo.githubusercontent.com/fe840de72b9c500418bd5dfedb0536641b3fa0139a7917f58997fe8dcc9f794e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230302d627269676874677265656e2e737667)](https://phpstan.org)[![psalm](https://camo.githubusercontent.com/c9399531f83db9ad38eace5e32a5d3e3382a79f64223deea86d32c3355952ecf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7073616c6d2d6c6576656c253230382d627269676874677265656e2e737667)](https://psalm.dev)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/769812eba163f42bf082b42abcb3a9a07338fca26683c57dcfea0d43e51a7d6a/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6265646974612f7068702d73646b2f6261646765732f7175616c6974792d73636f72652e706e67)](https://scrutinizer-ci.com/g/bedita/php-sdk/)[![Version](https://camo.githubusercontent.com/e8fe43346e830dae96a7a10558b5e01de9c9d430de8bb0574308d4e2ccc65726/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6265646974612f7068702d73646b2e7376673f6c6162656c3d737461626c65)](https://packagist.org/packages/bedita/php-sdk)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](https://github.com/bedita/php-sdk/blob/master/LICENSE.txt)

Prerequisites
-------------

[](#prerequisites)

- PHP &gt;= 8.3
- [Composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx)

Install
-------

[](#install)

To install the latest version of this library, run the command below:

```
composer require bedita/php-sdk
```

Basic Usage
-----------

[](#basic-usage)

### Init BEditaClient

[](#init-beditaclient)

Instantiate BEditaClient with API url and API key. This will usually be done via factory methods like [ApiclientProvider::getApiClient()](https://github.com/bedita/web-tools/blob/master/src/ApiClientProvider.php) that will read from environment variables and/or configuration files.

```
    $apiUrl = 'http://your-api-url';
    $apiKey = 'your-api-key';
    /** @var \BEdita\SDK\BEditaClient $client */
    $client = new BEditaClient($apiUrl, $apiKey);
```

### Init Logger for custom log

[](#init-logger-for-custom-log)

You can activate a detailed request/response log to file of API calls using `initLogger()` method. This will be also usually performed by factory methods like [ApiclientProvider::getApiClient()](https://github.com/bedita/web-tools/blob/master/src/ApiClientProvider.php).

```
   $client->initLogger(['log_file' => '/path/to/file/name.log']);
```

### Request Headers

[](#request-headers)

Some headers are handled as default in API calls:

- `Accept` as `application/vnd.api+json` to use JSON-API format
- `Content-Type` as `application/json` when a request body is set
- `Authorization` with `Bearer {token}` if a JWT token has been set
- `X-Api-Key` with the key passed to contructor

Upon every API call you can add new headers or overwrite defaults in the `$header` array argument (see below).

### Authenticate and tokens

[](#authenticate-and-tokens)

To retrieve or set JWT tokens you can:

- use `authenticate(string $username, string $password)` method to perform a classic username/password authentication
- use `setupTokens()` to set JWT tokens, retrieved from previous `authenticate` or other methods, for subsequent calls

```
    $response = (array)$client->authenticate('my-username', 'my-password');
    if (!empty($response['meta'])) {
        $client->setupTokens($response['meta']);
    }
```

On every subsequent API call JWT token will be used in `Authentication` header and expired token response will also be handled via refresh token automatically by the SDK.

### Direct API calls and utility methods

[](#direct-api-calls-and-utility-methods)

In order to use BEdita 4 API you have generally two options:

1. use direct API calls invoking POST/GET/PATCH/DELETE HTTP methods using correspondent `get()`/`post()`/`patch()`/`delete()` methods making sure that path, query string, body and headers are correctly populated;
2. use the utility methods explained below like `save`, `addRelated` and others to simplify settings and obtain a clearer code.

### Read objects and resources

[](#read-objects-and-resources)

You can use `getObjects(string $type = 'objects', ?array $query = null, ?array $headers = null)` to retrieve a list of objects by type, `getObject(int|string $id, string $type = 'objects', ?array $query = null, ?array $headers = null)` to get a single object by unique identifier and type.

Examples:

```
    // get documents
    $response = (array)$client->getObjects('documents'); // argument passed is a string $type

    // get documents using a filter
    $query = [
        'filter' => ['parent' => 'some-parent-id'],
    ];
    $response = (array)$client->getObjects('documents', $query); // arguments passed are string $type and array $query

    // get documents using a filter and more query options
    // include: including related data by relations "has_media" and "part_of"
    // lang: the desired lang (if translation is available)
    $query = [
        'filter' => ['parent' => 'some-parent-id'],
        'include' => 'has_media,part_of',
        'lang' => 'en',
    ];
    $response = (array)$client->getObjects('documents', $query); // arguments passed are string $type and array $query
```

```
    // get document 17823
    $response = (array)$client->getObject(17823, 'documents'); // arguments passed are int|string $id, string $type

    // get document 17823, english version, including related data by relations "has_media" and "part_of"
    $query = [
        'lang' => 'en',
        'include' => 'has_media,part_of',
    ];
    $response = (array)$client->getObject(17823, 'documents', ['lang' => 'en_EN']); // arguments passed are int|string $id, string $type and array $query

    // get folder website-footer
    $response = (array)$client->getObject('website-footer', 'folders'); // arguments passed are int|string $id, string $type
```

You can also use `get(string $path, ?array $query = null, ?array $headers = null)` to make an explicit GET API call, specifying the complete request path. This is the correct way to call special endpoints like `/home` or `/status` for instance (GET calls that are not used to retrieve objects o resources).

```
    // get API status
    $response = (array)$client->get('/status'); // argument passed is string $path

    // get API home info
    $response = (array)$client->get('/home'); // argument passed is string $path

    // get a list of documents
    $query = [
        'filter' => ['parent' => 'some-parent-id'],
    ];
    $response = (array)$client->get('/documents', $query); // arguments passed are string $path and array $query

    // get a stream by id
    $response = (array)$client->get('/streams/the-stream-id'); // argument passed is string $path
```

When you need to get relationships related data, you can you `getRelated(int|string $id, string $type, string $relation, ?array $query = null, ?array $headers = null)`.

```
    // get subfolders for a folder with ID 888
    $query = [
        'filter' => ['type' => 'folders'],
    ];
    $subfolders = $client->getRelated(888, 'folders', 'children', $query); // arguments passed are int|string $id, string $type, string $relation, array $query

    // get children (all types) inside a folder with unique name 'my-folder-uname'
    $children = $client->getRelated('my-folder-uname', 'folders', 'children'); // arguments passed are int|string $id, string $type, string $relation
```

### Save objects and resources

[](#save-objects-and-resources)

You can use `save(string $type, array $data, ?array $headers = null)` method: this is the standard method to use to create or update objects or resources in BEdita 4. Please note that the payload is made of object attributes, without the need to specify a `data.attribute` section that you must use when dealing with direct POST o PATCH API calls.

Example:

```
    // save a new document
    $data = [
        'title' => 'My new doc',
        'status' => 'on',
    ];
    $response = (array)$client->save('documents', $data); // arguments passed are string $type, array $data
    // retrocompatibility version with saveObject, deprecated
    $response = (array)$client->saveObject('documents', $data); // arguments passed are string $type, array $data

    // save an existing document
    $data = [
        'id' => 999,
        'title' => 'My new doc, changed title',
    ];
    $response = (array)$client->save('documents', $data); // arguments passed are string $type, array $data
    // retrocompatibility version with saveObject, deprecated
    $response = (array)$client->saveObject('documents', $data); // arguments passed are string $type, array $data
```

`save` and `saveObject` use internally `patch(string $path, mixed $body, ?array $headers = null)` (when saving an existing object) or `post(string $path, mixed $body, ?array $headers = null)` (when saving a new object).

If you like to use them directly:

```
    // save a new document
    $data = [
        'type' => 'documents',
        'attributes' => [
            'title' => 'My doc',
            'status' => 'on',
        ],
    ];
    $response = (array)$client->post('/documents', $data); // arguments passed are string $path, array $data

    // save an existing document
    $data = [
        'type' => 'documents',
        'attributes' => [
            'title' => 'My doc',
            'status' => 'on',
        ],
    ];
    $response = (array)$client->post('/documents/999', $data); // arguments passed are string $path, array $data
```

### Delete and restore data

[](#delete-and-restore-data)

#### Soft delete

[](#soft-delete)

Soft delete puts object into the trashcan. You can trash an object with `delete(string $path, mixed $body = null, ?array $headers = null)` or `deleteObject(int|string $id, string $type)`.

```
    // delete document by ID 99999
    $response = $client->delete('/documents/99999'); // argument passed is string $path

    // delete document by ID 99999 and type documents
    $response = $client->deleteObject(99999, 'documents'); // arguments passed are string|int $id, string $type

    // delete multiple
    $response = $client->deleteObjects([999991, 999992, 999993], 'documents');
```

#### Restore data

[](#restore-data)

Data in trashcan can be restored with `restoreObject(int|string $id, string $type)`.

```
    // restore document 99999
    $response = $client->restoreObject(99999, 'documents'); // arguments passed are string|int $id, string $type

    // restore multiple
    $response = $client->restoreObjects([999991, 999992, 999993], 'documents');
```

#### Hard delete

[](#hard-delete)

Hard delete removes object from trashcan. You can remove an object from trashcan with `remove(int|string $id)`.

```
    // delete document by ID 99999
    $response = $client->deleteObject(99999, 'documents'); // arguments passed are string|int $id, string $type

    // permanently remove documents 99999
    $response = $client->remove(99999); // argument passed is string|int $id

    // permanently remove multiple
    $response = $client->removeObjects([999991, 999992, 999993]);
```

### Working with relations

[](#working-with-relations)

#### Add related objects

[](#add-related-objects)

You can add related objects using `addRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null)`.

```
    // save a document and add related objects, in this example a "see_also" relation between documents and documents is involved
    $document = $client->save('documents', ['title' => 'My new doc']);
    $relatedData = [
        [
            'id' => 9999, // another doc id
            'type' => 'documents',
        ],
    ];
    $client->addRelated($document['data']['id'], 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData
```

#### Replace related objects

[](#replace-related-objects)

`replaceRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null)` is handy to replace related objects.

```
    // replace related objects, in this example a "see_also" relation between document 8888 and document 9999
    $relatedData = [
        [
            'id' => 9999,
            'type' => 'documents',
        ],
    ];
    $client->replaceRelated(8888, 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData
```

Note: internally `addRelated` uses `post` and `replaceRelated` uses `patch`. Both will call `/:type/:id/relationships/:relation`

#### Remove related objects

[](#remove-related-objects)

Related objects can be removed using `removeRelated(int|string $id, string $type, string $relation, array $data, ?array $headers = null)`.

```
    // remove related data, in this example a "see_also" relation between document 8888 and document 9999
    $relatedData = [
        [
            'id' => 9999,
            'type' => 'documents',
        ],
    ];
    $client->removeRelated(8888, 'documents', 'see_also', $relatedData); // arguments passed are int|string $id, string $type, string $relation, array $relationData
```

### Upload

[](#upload)

The easiest way to create a new media object with file upload is to call a POST with file content as body.

Example of image upload:

```
    $content = file_get_contents('/path/to/image.png');

    $response = $client->post('/images/upload/image.png',
        $content,
        ['Content-type' => 'image/png']
    );
```

A new object of type `images` will be created having `image.png` file as related stream resource. If you need instead to handle more low level actions via streams read the paragraphs below.

#### Upload streams

[](#upload-streams)

Use `upload(string $filename, string $filepath, ?array $headers = null)` to perform a `POST /streams/upload/:filename` and create a new stream with your file.

```
    // upload the image /home/gustavo/sample.jpg
    $response = $client->upload('sample.jpg', '/home/gustavo/sample.jpg');
```

Note: if you don't pass `$headers` argument, the function uses `mime_content_type($filepath)`.

```
    // upload the image /home/gustavo/sample.jpg, passing content type
    $response = $client->upload('sample.jpg', '/home/gustavo/sample.jpg', ['Content-type' => 'image/jpeg']);
```

#### Create media from stream

[](#create-media-from-stream)

You create a media object from a stream with `createMediaFromStream(string $streamId, string $type, array $body)`. This basically makes 3 calls:

- `POST /:type` with `$body` as payload, create media object
- `PATCH /streams/:stream_id/relationships/object` modify stream adding relation to media
- `GET /:type/:id` get media data

```
    // upload an audio file
    $filepath = '/home/gustavo/sample.mp3';
    $filename = basename($filepath);
    $headers = ['Content-type' => 'audio/mpeg'];
    $response = $client->upload($filename, $filepath, $headers);

    // create media from stream
    $streamId = Hash::get($response, 'data.id');
    $body = [
        'data' => [
            'type' => 'audios',
            'attributes' => [
                'title' => $filename,
                'status' => 'on',
            ],
        ],
    ];
    $response = $client->createMediaFromStream($id, $type, $body);
```

### Thumbnails

[](#thumbnails)

Media thumbnails can be retrived using `thumbs(int|null $id, $query = [])`.

Usage:

```
    // get thumbnail for media 123 => GET /media/thumbs/123
    $client->thumbs(123);

    // get thumbnail for media 123 with a preset => GET /media/thumbs/123&preset=glide
    $client->thumbs(123, ['preset' => 'glide']);

    // get thumbnail for multiple media => GET /media/thumbs?ids=123,124,125
    $client->thumbs(null, ['ids' => '123,124,125']);

    // get thumbnail for multiple media with a preset => GET /media/thumbs?ids=123,124,125&preset=async
    $client->thumbs(null, ['ids' => '123,124,125', 'preset' => 'async']);

    // get thumbnail media 123 with specific options (these options could be not available... just set in preset(s)) => GET /media/thumbs/123/options[w]=100&options[h]=80&options[fm]=jpg
    $client->thumbs(123, ['options' => ['w' => 100, 'h' => 80, 'fm' => 'jpg']]);
```

### Schema

[](#schema)

You can get the JSON SCHEMA of a resource or object with `schema(string $type)`.

```
    // get schema of users => GET /model/schema/users
    $schema = $client->schema('users');
```

Get info of a relation (data, params) and get left/right object types using `relationData(string $name)`.

```
    // get relation data of relation see_also => GET /model/relations/see_also
    $schema = $client->relationData('see_also');
```

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance57

Moderate activity, may be stable

Popularity36

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity87

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~125 days

Recently: every ~80 days

Total

22

Last Release

210d ago

Major Versions

v1.2.0 → v2.0.02022-03-14

v2.1.1 → v3.0.02024-09-09

v3.1.2 → v4.0.02024-12-03

PHP version history (4 changes)v1.0.0PHP &gt;=7.1

v2.0.0PHP &gt;=7.4

v4.0.0PHP &gt;=8.1

v4.1.0PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/00305fda0159b5d71f7bd6848ae7d3f7ac27d0179d79d58c4847848c8bd673e0?d=identicon)[fquffio](/maintainers/fquffio)

![](https://www.gravatar.com/avatar/c645e2da27d7328271f360d21cc93971eebe29b3bec837370684ef1c6991d7d7?d=identicon)[bato](/maintainers/bato)

![](https://www.gravatar.com/avatar/33c95e1516af3f48ebb2057caafd7f331a7aaae58c52442f8e8d00e03b211da9?d=identicon)[stefanorosanelli](/maintainers/stefanorosanelli)

![](https://www.gravatar.com/avatar/8762bf55fa377228164991afe77ca94b7384eb1f5ed79781cad7835624cc27c3?d=identicon)[d.didomenico](/maintainers/d.didomenico)

---

Top Contributors

[![didoda](https://avatars.githubusercontent.com/u/2227145?v=4)](https://github.com/didoda "didoda (89 commits)")[![stefanorosanelli](https://avatars.githubusercontent.com/u/2122280?v=4)](https://github.com/stefanorosanelli "stefanorosanelli (82 commits)")[![edoardocavazza](https://avatars.githubusercontent.com/u/3907295?v=4)](https://github.com/edoardocavazza "edoardocavazza (17 commits)")[![batopa](https://avatars.githubusercontent.com/u/1306319?v=4)](https://github.com/batopa "batopa (5 commits)")[![vallo87](https://avatars.githubusercontent.com/u/3777317?v=4)](https://github.com/vallo87 "vallo87 (5 commits)")[![fquffio](https://avatars.githubusercontent.com/u/7108146?v=4)](https://github.com/fquffio "fquffio (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[googleads/googleads-php-lib

Google Ad Manager SOAP API Client Library for PHP

67410.3M25](/packages/googleads-googleads-php-lib)[googleads/google-ads-php

Google Ads API client for PHP

3497.6M9](/packages/googleads-google-ads-php)[team-reflex/discord-php

An unofficial API to interact with the voice and text service Discord.

1.1k379.4k24](/packages/team-reflex-discord-php)[wheelpros/fitment-platform-api

Magento 2 (Open Source)

12.1k1.2k](/packages/wheelpros-fitment-platform-api)[checkout/checkout-sdk-php

Checkout.com SDK for PHP

553.3M7](/packages/checkout-checkout-sdk-php)

PHPackages © 2026

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