Skip to content

API

Office App, if configured, now provides an API for sharing data.

General Configuration

In config.php enable API and define tokens:

// ...
'api' => [
        'enabled' => true,
        'tokens' => [
            '...' => ['label' => 'Token-A'],
            '...' => ['label' => 'Token-B'],
            // ...
        ],
    ],
// ...

Per Model Configuration

In model, define which columns (all | whitelist | blacklist) shall be published in API:

All columns

1
2
3
4
public static function apiPublish(): array|false
{
    return []; // publish ALL columns
}

Whitelisted columns

1
2
3
4
5
public static function apiPublish(): array|false
{
    // publish given columns
    return ['whitelist' => ['id', 'subject', 'notes']];
}

All but blacklisted columns

1
2
3
4
public static function apiPublish(): array|false
{
    return ['blacklist' => ['attachments','watchers','notes','content','last_modified_on']];
}

Disable API per Model

1
2
3
4
public static function apiPublish(): array|false
{
    return false;
}

Cascading

Using hasMany-feature we can create lists of related records like a Ticket has many notes (TicketNote).

$this->hasMany("notes", TicketNote::class, "ticket_id"),

Now, the API not only allows us to fetch tickets...

GET {{base_url}}/ticket

... but also tickets with their joined notes:

GET {{base_url}}/ticket/?join=notes

Of course, the joined notes will only be transmitted if the API for the TicketNode model is implemented.

Filters

Get Record By ID

GET {{base_url}}/ticket/2

Find Record by criteria

Search for Ticket #2 in subject column of Ticket-model:

GET {{base_url}}/ticket?subject=Ticket%20%232

Important
You need to encode your request, for example searchterm Ticket #2 contains two special characters which must be encoded,  (blank character) and #.

Ticket #2Ticket%20%232

Your programming language will have helper-functions for such URL-Component-Encoding

GET {{base_url}}/ticket?subject=Ticket%20%232

Example

Assume that the API is enabled and configured to all for both, Ticket and TicketNode and that we have a valid token:

GET {{base_url}}/ticket/?join=notes

alt text

{
    "data": [
        {
            "id": 2,
            "subject": "Ticket #2",
            "notes": []
        },
        {
            "id": 4,
            "subject": "Ticket #3",
            "notes": []
        },
        {
            "id": 5,
            "subject": "Ticket #4",
            "notes": []
        },
        {
            "id": 6,
            "subject": "Ticket #5 (Test KSE)",
            "notes": [
                {
                    "id": 2,
                    "subject": "Ticket #3",
                    "content": " µbv µ",
                    "ticket_id": 6,
                    "ticket_label": "Ticket #5 (Test KSE)",
                    "owner_id": 1,
                    "owner_label": "admin",
                    "pdfs": [
                        "d4c2a106c42d143b.pdf"
                    ]
                }
            ]
        }
    ],
    "meta": {
        "total": 4,
        "page": 1,
        "per_page": 50,
        "total_pages": 1
    }
}

Endpoint Examples

1
2
3
4
5
6
7
8
GET /api.php/note                           → paginated list (?page=1&per_page=50)
GET /api.php/note?subject=Foo               → filtered by column equality
GET /api.php/note?subject=Foo%20Fighters
GET /api.php/note/1                         → single record
GET /api.php/note/1?join=record             → with joined reference data (if target is API-published)

DISABLED BY DEFAULT:
GET /api.php                                → schema index (lists published models + field types)