PHPackages                             graystackit/laravel-helpspace-api - 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. graystackit/laravel-helpspace-api

ActiveLibrary[API Development](/categories/api)

graystackit/laravel-helpspace-api
=================================

Laravel package for the HelpSpace API, built on Saloon 4

00PHP

Since May 19Pushed 3w agoCompare

[ Source](https://github.com/GraystackIT/laravel-helpspace-api)[ Packagist](https://packagist.org/packages/graystackit/laravel-helpspace-api)[ RSS](/packages/graystackit-laravel-helpspace-api/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

graystackit/laravel-helpspace-api
=================================

[](#graystackitlaravel-helpspace-api)

A Laravel package for the [HelpSpace API](https://documentation.helpspace.com/), built on [Saloon 4](https://docs.saloon.dev/).

Supports **Tickets**, **Messages**, **Reports**, and **Webhooks**.

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 11, 12, or 13

Installation
------------

[](#installation)

```
composer require graystackit/laravel-helpspace-api
```

The service provider is auto-discovered by Laravel.

Publish the config file:

```
php artisan vendor:publish --tag=helpspace-config
```

Add your credentials to `.env`:

```
HELPSPACE_API_KEY=your-bearer-token
HELPSPACE_CLIENT_ID=your-client-id
HELPSPACE_BASE_URL=https://api.helpspace.com
```

---

Configuration
-------------

[](#configuration)

After publishing, the config file lives at `config/helpspace.php`:

```
return [
    'api_key'  => env('HELPSPACE_API_KEY'),
    'client_id' => env('HELPSPACE_CLIENT_ID'),
    'base_url' => env('HELPSPACE_BASE_URL', 'https://api.helpspace.com'),

    'defaults' => [
        'per_page' => 20,
    ],
];
```

---

Usage
-----

[](#usage)

Resolve `HelpSpaceClient` from the container or inject it via the constructor:

```
use GraystackIT\HelpSpace\HelpSpaceClient;

class SupportController extends Controller
{
    public function __construct(private HelpSpaceClient $helpspace) {}
}
```

---

Tickets
-------

[](#tickets)

**API reference:**

### List tickets

[](#list-tickets)

```
$result = $this->helpspace->listTickets(
    perPage:  25,
    statuses: ['open', 'escalated'],
    contacts: ['customer@example.com'],
    tags:     ['billing'],
    createdBetween: '2024-01-01/2024-01-31',
);

foreach ($result['data'] as $ticket) {
    echo $ticket->id;           // int
    echo $ticket->subject;      // string
    echo $ticket->status;       // string (open|closed|waiting|escalated|spam|unassigned)
    echo $ticket->contactEmail; // string|null
    echo $ticket->contactName;  // string|null
    echo $ticket->assigneeName; // string|null
    echo $ticket->teamName;     // string|null
    print_r($ticket->tags);     // array
    echo $ticket->createdAt;    // ISO 8601 string
}

// Pagination metadata
$result['meta'];   // ['current_page' => 1, 'total' => 120, ...]
$result['links'];  // ['next' => '...', 'prev' => null, ...]
```

#### `listTickets()` parameters

[](#listtickets-parameters)

ParameterTypeDefaultDescription`$perPage``int``20` (max 50)Results per page`$statuses``string[]``[]`Filter by status values`$contacts``string[]``[]`Filter by contact email`$assignees``string[]``[]`Filter by assignee name or ID`$tags``string[]``[]`Filter by tag names`$subjects``string[]``[]`Filter by subject text`$bodies``string[]``[]`Filter by body text`$subjectOrBody``string[]``[]`Filter by subject or body`$organizations``string[]``[]`Filter by organization`$teams``string[]``[]`Filter by team`$createdBetween``string|null``null`Date range `YYYY-MM-DD/YYYY-MM-DD``$lastContactBetween``string|null``null`Date range `YYYY-MM-DD/YYYY-MM-DD`**`TicketStatus` enum values:**

CaseAPI value`Unassigned``unassigned``Open``open``Escalated``escalated``Spam``spam``Waiting``waiting``Closed``closed`### Get a ticket

[](#get-a-ticket)

```
$ticket = $this->helpspace->getTicket(101);
```

### Create a ticket

[](#create-a-ticket)

```
$ticket = $this->helpspace->createTicket([
    'subject'      => 'Cannot access my account',
    'channel'      => ['id' => 'channel-uuid'],
    'from_contact' => ['email' => 'user@example.com', 'name' => 'John Doe'],
    'message'      => ['body' => 'I cannot log in since yesterday.'],
    'tags'         => ['access', 'urgent'],
    // Optional:
    'skip_autoreply'      => false,
    'skip_notifications'  => false,
]);
```

### Update a ticket

[](#update-a-ticket)

```
$ticket = $this->helpspace->updateTicket(101, [
    'status'   => 'closed',
    'assignee' => ['id' => 'agent-uuid'],
]);
```

### Delete a ticket

[](#delete-a-ticket)

Soft-deleted tickets are permanently removed after 30 days.

```
$this->helpspace->deleteTicket(101); // returns true
```

---

Messages
--------

[](#messages)

**API reference:**

### List messages

[](#list-messages)

Default types returned: `external`, `widget`, `forward`.

```
// Default message types
$messages = $this->helpspace->listMessages(101);

// Include internal notes as well
$messages = $this->helpspace->listMessages(101, additionalTypes: ['internal']);

// Only return internal notes
$messages = $this->helpspace->listMessages(101, types: ['internal']);

foreach ($messages as $message) {
    echo $message->id;               // int
    echo $message->type;             // external|internal|forward|widget|...
    echo $message->fromContactEmail; // string
    echo $message->fromContactName;  // string
    echo $message->body;             // HTML string
    echo $message->createdAt;        // ISO 8601 string
    print_r($message->attachments);  // array
    print_r($message->to);           // array of recipient addresses
}
```

**`MessageType` enum values:**

CaseAPI valueDefault returned`External``external`Yes`Widget``widget`Yes`Forward``forward`Yes`Internal``internal`No`Error``error`No`Bounce``bounce`No`Event``event`No`AiSummary``ai-summary`No### Get a message

[](#get-a-message)

```
$message = $this->helpspace->getMessage(ticketId: 101, messageId: 77);
```

### Create a message

[](#create-a-message)

```
$message = $this->helpspace->createMessage(101, [
    'from_contact' => ['email' => 'agent@example.com', 'name' => 'Support Agent'],
    'subject'      => 'Re: Cannot access my account',
    'body'         => 'We have reset your password. Please check your email.',
    // Optional:
    'type'                  => 'external',      // default
    'to'                    => ['user@example.com'],
    'cc'                    => [],
    'bcc'                   => [],
    'skip_notifications'    => false,
    'send_mail_to_recipients' => true,
    // Attachments as base64 (max 5 MB combined)
    'attachments' => [
        ['file_name' => 'guide.pdf', 'mime_type' => 'application/pdf', 'data' => base64_encode($pdfBytes)],
    ],
]);
```

---

Reports
-------

[](#reports)

**API reference:**

### Channels report

[](#channels-report)

```
$report = $this->helpspace->getChannelsReport('2024-01-01', '2024-01-31');

print_r($report->dailyCounts);  // per-day opened/closed ticket counts
print_r($report->metrics);      // new, closed, open, waiting, escalated counts
print_r($report->channels);     // ticket volume by channel
print_r($report->tags);         // ticket volume by tag
print_r($report->topCustomers); // customers with most tickets
print_r($report->raw);          // full raw API response
```

### Performance report

[](#performance-report)

```
$report = $this->helpspace->getPerformanceReport('2024-01-01', '2024-01-31');

print_r($report->dailyCounts);  // per-day opened/closed counts
print_r($report->metrics);      // avg resolution time breakdown (days/hours/minutes)
print_r($report->topAgents);    // agents with most resolved tickets
print_r($report->raw);          // full raw API response
```

Both methods accept date strings in `YYYY-MM-DD` format. An `InvalidArgumentException` is thrown if either date is empty.

---

Webhooks
--------

[](#webhooks)

**API reference:**

### Get webhook configuration

[](#get-webhook-configuration)

```
$config = $this->helpspace->getWebhook();

echo $config->enabled;     // bool
echo $config->url;         // destination URL
echo $config->secret;      // validation hash (string|null)
print_r($config->headers); // custom headers [['key' => '...', 'value' => '...']]
print_r($config->trigger); // enabled event types per resource
echo $config->failedCount; // consecutive failure count (auto-disables on too many)
```

### Update webhook configuration

[](#update-webhook-configuration)

```
$config = $this->helpspace->updateWebhook([
    'enabled' => true,
    'url'     => 'https://myapp.example.com/webhooks/helpspace',
    'secret'  => 'my-validation-secret',
    'headers' => [
        ['key' => 'X-App-Key', 'value' => 'my-app-key'],
    ],
    'trigger' => [
        'ticket'   => ['created' => true, 'updated' => true, 'deleted' => false],
        'customer' => ['created' => false],
        'tag'      => ['created' => false],
    ],
]);
```

### Get webhook error logs

[](#get-webhook-error-logs)

```
$logs = $this->helpspace->getWebhookLogs();

foreach ($logs as $log) {
    echo $log['status'];     // HTTP status code returned by your endpoint
    echo $log['response'];   // response body
    echo $log['created_at']; // when the failure occurred
}
```

---

Exceptions
----------

[](#exceptions)

ExceptionWhen thrown`HelpSpaceApiException`API returned 4xx/5xx, network failure, or non-JSON response`InvalidArgumentException`Empty subject on `createTicket()`, empty body on `createMessage()`, or empty dates on report methods---

Testing
-------

[](#testing)

This package uses Saloon's `MockClient` so you can test without real HTTP calls:

```
use GraystackIT\HelpSpace\HelpSpaceClient;
use GraystackIT\HelpSpace\Connectors\HelpSpaceConnector;
use GraystackIT\HelpSpace\Requests\Tickets\ListTicketsRequest;
use Saloon\Http\Faking\MockClient;
use Saloon\Http\Faking\MockResponse;

$mockClient = new MockClient([
    ListTicketsRequest::class => MockResponse::make([
        'data'  => [
            [
                'id'           => 1,
                'subject'      => 'Test ticket',
                'status'       => 'open',
                'from_contact' => ['email' => 'user@example.com', 'name' => 'User'],
                'created_at'   => '2024-01-01T00:00:00Z',
            ],
        ],
        'meta'  => [],
        'links' => [],
    ], 200),
]);

$connector = app(HelpSpaceConnector::class);
$connector->withMockClient($mockClient);

$result = (new HelpSpaceClient($connector))->listTickets();
```

Run the package test suite:

```
composer install
vendor/bin/pest
```

---

API Endpoints Reference
-----------------------

[](#api-endpoints-reference)

MethodHTTPHelpSpace API Endpoint`listTickets()`GET`/api/v1/tickets``getTicket()`GET`/api/v1/tickets/{id}``createTicket()`POST`/api/v1/tickets``updateTicket()`PATCH`/api/v1/tickets/{id}``deleteTicket()`DELETE`/api/v1/tickets/{id}``listMessages()`GET`/api/v1/tickets/{id}/messages``getMessage()`GET`/api/v1/tickets/{id}/messages/{messageId}``createMessage()`POST`/api/v1/tickets/{id}/messages``getChannelsReport()`POST`/api/v1/reports/channels``getPerformanceReport()`POST`/api/v1/reports/performance``getWebhook()`GET`/api/v1/webhook``updateWebhook()`POST`/api/v1/webhook``getWebhookLogs()`GET`/api/v1/webhook/logs`---

License
-------

[](#license)

MIT

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance62

Regular maintenance activity

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 87.5% of commits — single point of failure

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.

### Community

Maintainers

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

---

Top Contributors

[![Parvesh96](https://avatars.githubusercontent.com/u/96613912?v=4)](https://github.com/Parvesh96 "Parvesh96 (7 commits)")[![bharb82](https://avatars.githubusercontent.com/u/159435438?v=4)](https://github.com/bharb82 "bharb82 (1 commits)")

### Embed Badge

![Health badge](/badges/graystackit-laravel-helpspace-api/health.svg)

```
[![Health](https://phpackages.com/badges/graystackit-laravel-helpspace-api/health.svg)](https://phpackages.com/packages/graystackit-laravel-helpspace-api)
```

###  Alternatives

[facebook/php-business-sdk

PHP SDK for Facebook Business

90923.5M35](/packages/facebook-php-business-sdk)[hubspot/api-client

Hubspot API client

24015.5M18](/packages/hubspot-api-client)[botman/driver-telegram

Telegram driver for BotMan

93452.6k6](/packages/botman-driver-telegram)

PHPackages © 2026

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