yannelli/pocket-laravel

Laravel SDK for the Pocket API - Access recordings, transcripts, summaries, and more

Fund package maintenance!
:vendor_name

Installs: 134

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/yannelli/pocket-laravel

v1.1.1 2026-01-22 00:33 UTC

This package is auto-updated.

Last update: 2026-01-22 00:36:03 UTC


README

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Introduction

Pocket Laravel SDK provides an expressive, fluent interface for interacting with the Pocket API. Using this SDK, you may easily access your recordings, transcripts, summaries, and action items from within your Laravel application.

The SDK handles authentication, request building, pagination, retry logic with exponential backoff, and exception mapping—allowing you to focus on building your application rather than managing HTTP requests.

Installation

You may install the Pocket Laravel SDK via the Composer package manager:

composer require yannelli/pocket-laravel

After installing the package, the service provider will be automatically registered via Laravel's package discovery.

Configuration

Before using the SDK, you will need to configure your Pocket API credentials. First, publish the configuration file using the vendor:publish Artisan command:

php artisan vendor:publish --tag="pocket-config"

This command will publish a pocket.php configuration file to your application's config directory:

return [
    'api_key' => env('POCKET_API_KEY'),
    'base_url' => env('POCKET_BASE_URL', 'https://public.heypocketai.com'),
    'api_version' => env('POCKET_API_VERSION', 'v1'),
    'timeout' => env('POCKET_TIMEOUT', 30),
    'retry' => [
        'times' => env('POCKET_RETRY_TIMES', 3),
        'sleep' => env('POCKET_RETRY_SLEEP', 1000),
    ],
];

Next, add your Pocket API key to your application's .env file:

POCKET_API_KEY=pk_your_api_key_here

Making Requests

Using the Facade

The SDK provides a Pocket facade that allows you to fluently access all available resources:

use Yannelli\Pocket\Facades\Pocket;

// List recordings
$recordings = Pocket::recordings()->list();

// Get a specific recording
$recording = Pocket::recordings()->get('rec_123');

// List folders
$folders = Pocket::folders()->list();

// List tags
$tags = Pocket::tags()->list();

Using Dependency Injection

If you prefer dependency injection, you may type-hint the Pocket class in your controller's constructor or method signatures. The SDK's service provider binds the Pocket class as a singleton, ensuring the same instance is resolved throughout your application:

use Yannelli\Pocket\Pocket;

class RecordingController extends Controller
{
    public function __construct(
        private Pocket $pocket
    ) {}

    public function index()
    {
        return $this->pocket->recordings()->list();
    }
}

Multi-Tenant Applications

For multi-tenant applications where each tenant may have their own Pocket API key, you may use the withApiKey method to create a new SDK instance with a different API key. All other configuration options are preserved from the original instance:

use Yannelli\Pocket\Facades\Pocket;

// Create a tenant-specific instance
$tenantPocket = Pocket::withApiKey($tenant->pocket_api_key);

// Use the tenant-specific instance
$recordings = $tenantPocket->recordings()->list();

You may also create multiple tenant instances from a single base configuration:

use Yannelli\Pocket\Pocket;

class TenantRecordingService
{
    public function __construct(
        private Pocket $pocket
    ) {}

    public function getRecordingsForTenant(Tenant $tenant)
    {
        return $this->pocket
            ->withApiKey($tenant->pocket_api_key)
            ->recordings()
            ->list();
    }
}

Note

The withApiKey method returns a new Pocket instance. The original instance remains unchanged, making it safe to use in concurrent or queued operations.

Recordings

The recordings resource provides methods for listing, filtering, and retrieving recordings along with their associated transcripts, summaries, and action items.

Retrieving Recordings

To retrieve a paginated list of recordings, you may use the list method:

use Yannelli\Pocket\Facades\Pocket;

$recordings = Pocket::recordings()->list();

foreach ($recordings as $recording) {
    echo $recording->title;
    echo $recording->formattedDuration(); // "1:30:45"
}

The list method returns a PaginatedRecordings instance. You may check for additional pages and retrieve subsequent results:

if ($recordings->hasMore()) {
    $nextPage = Pocket::recordings()->list(page: $recordings->nextPage());
}

To retrieve a single recording by its ID, use the get method:

$recording = Pocket::recordings()->get('rec_123');

Filtering Recordings

The recordings resource provides several convenient methods for filtering results. You may filter recordings by folder:

$recordings = Pocket::recordings()->inFolder('folder_123');

To filter by tags, pass an array of tag IDs to the withTags method:

$recordings = Pocket::recordings()->withTags(['tag_1', 'tag_2']);

You may also filter recordings within a specific date range:

$recordings = Pocket::recordings()->betweenDates('2025-01-01', '2025-01-31');

For more complex filtering, the list method accepts all filter parameters directly:

$recordings = Pocket::recordings()->list(
    folderId: 'folder_123',
    startDate: '2025-01-01',
    endDate: '2025-01-31',
    tagIds: ['tag_1', 'tag_2'],
    page: 1,
    limit: 50
);

Iterating All Recordings

When you need to process all recordings, the all method returns a generator that automatically handles pagination:

foreach (Pocket::recordings()->all() as $recording) {
    echo $recording->title;
}

You may also apply filters when iterating all recordings:

foreach (Pocket::recordings()->all(folderId: 'folder_123') as $recording) {
    // Process recording...
}

Note

The all method uses PHP generators to efficiently iterate through large result sets without loading all recordings into memory at once.

Recording Details

When retrieving a single recording, you may control which related data is included in the response. By default, all related data is included. To exclude specific data and improve response times:

$recording = Pocket::recordings()->get(
    id: 'rec_123',
    includeTranscript: false,
    includeSummary: true,
    includeActionItems: true
);

Transcripts

Recordings may include transcript data with speaker identification and time-coded segments. You may access the transcript through the recording instance:

$recording = Pocket::recordings()->get('rec_123');

if ($recording->hasTranscript()) {
    // Access the full transcript text
    echo $recording->transcript->text;

    // Get a list of speakers
    $speakers = $recording->transcript->speakers();

    // Retrieve segments for a specific speaker
    $segments = $recording->transcript->segmentsForSpeaker('Speaker 1');
}

Summaries

Recordings may include AI-generated summaries organized into sections:

if ($recording->hasSummary()) {
    echo $recording->summary->title;

    foreach ($recording->summary->sections as $section) {
        echo $section->heading;
        echo $section->content;
    }
}

Action Items

Recordings may include extracted action items with priority levels and completion status:

if ($recording->hasActionItems()) {
    // Filter by status
    $pendingItems = $recording->pendingActionItems();
    $completedItems = $recording->completedActionItems();

    foreach ($recording->actionItems as $item) {
        echo $item->title;
        echo $item->priority->label(); // "High", "Medium", "Low"

        if ($item->isOverdue()) {
            // Handle overdue item...
        }
    }
}

Recording States

Recordings progress through various processing states. You may inspect a recording's current state using the following methods:

$recording = Pocket::recordings()->get('rec_123');

if ($recording->isProcessing()) {
    echo "Recording is being processed...";
}

if ($recording->isCompleted()) {
    echo "Recording is ready!";
}

if ($recording->isFailed()) {
    echo "Processing failed: " . $recording->state->description();
}

The available recording states are: pending, transcribing, failed, transcribed, summarizing, summarization_failed, completed, and unknown.

Folders

The folders resource allows you to list and retrieve folders:

use Yannelli\Pocket\Facades\Pocket;

// List all folders
$folders = Pocket::folders()->list();

// Find a folder by ID
$folder = Pocket::folders()->find('folder_123');

// Find a folder by name
$folder = Pocket::folders()->findByName('Work Meetings');

// Get the default folder
$defaultFolder = Pocket::folders()->default();

Tags

The tags resource provides methods for listing and finding tags:

use Yannelli\Pocket\Facades\Pocket;

// List all tags (ordered by usage)
$tags = Pocket::tags()->list();

// Get most used tags
$topTags = Pocket::tags()->mostUsed(5);

// Find a tag by ID
$tag = Pocket::tags()->find('tag_123');

// Find a tag by name
$tag = Pocket::tags()->findByName('Important');

Audio

The audio resource provides methods for accessing and downloading audio files associated with recordings.

Retrieving Audio URLs

To get a signed URL for a recording's audio file:

use Yannelli\Pocket\Facades\Pocket;

$audioUrl = Pocket::audio()->getUrl('rec_123');

echo $audioUrl->signedUrl;
echo $audioUrl->expiresIn; // Seconds until expiry

Signed URLs expire after a period of time. You may check if a URL has expired and retrieve a fresh one:

if ($audioUrl->isExpired()) {
    $audioUrl = Pocket::audio()->getUrl('rec_123');
}

Downloading Audio

The SDK provides several methods for downloading audio content:

// Get the audio file contents as a string
$contents = Pocket::audio()->getContents('rec_123');

// Stream the audio file (memory efficient for large files)
$stream = Pocket::audio()->stream('rec_123');

// Download to a temporary file (auto-cleaned up on script end)
$tempPath = Pocket::audio()->download('rec_123');

You may also save audio files directly to Laravel's filesystem:

// Save to a Laravel storage disk
Pocket::audio()->saveTo('recordings/audio.mp3', 's3', [], 'rec_123');

// Save using streaming (memory efficient)
Pocket::audio()->saveStreamTo('recordings/audio.mp3', 'local', [], 'rec_123');

// Save directly to a local path
Pocket::audio()->saveToPath('/path/to/audio.mp3', 'rec_123');

To manually clean up temporary files created by the download method:

use Yannelli\Pocket\Resources\AudioResource;

AudioResource::cleanup();

Scoped Audio Resource

When working with a single recording's audio, you may create a scoped audio resource to simplify method calls:

$audio = Pocket::audio('rec_123');

// All methods now work without passing the recording ID
$url = $audio->getUrl();
$contents = $audio->getContents();
$tempPath = $audio->download();

Error Handling

The SDK throws specific exceptions based on the HTTP response status code. You may catch these exceptions to handle different error conditions:

use Yannelli\Pocket\Facades\Pocket;
use Yannelli\Pocket\Exceptions\AuthenticationException;
use Yannelli\Pocket\Exceptions\NotFoundException;
use Yannelli\Pocket\Exceptions\RateLimitException;
use Yannelli\Pocket\Exceptions\ValidationException;
use Yannelli\Pocket\Exceptions\ServerException;
use Yannelli\Pocket\Exceptions\PocketException;

try {
    $recording = Pocket::recordings()->get('rec_123');
} catch (AuthenticationException $e) {
    // Invalid API key (401)
} catch (NotFoundException $e) {
    // Recording not found (404)
} catch (RateLimitException $e) {
    // Too many requests (429)
    $retryAfter = $e->getRetryAfter();
} catch (ValidationException $e) {
    // Invalid parameters (400)
    $details = $e->getDetails();
} catch (ServerException $e) {
    // Server error (5xx)
} catch (PocketException $e) {
    // Any other API error
}

Note

The RateLimitException provides a getRetryAfter() method that returns the number of seconds you should wait before making another request.

Configuration Reference

The following configuration options are available:

Option Environment Variable Default Description
api_key POCKET_API_KEY — Your Pocket API key
base_url POCKET_BASE_URL https://public.heypocketai.com API base URL
api_version POCKET_API_VERSION v1 API version
timeout POCKET_TIMEOUT 30 Request timeout in seconds
retry.times POCKET_RETRY_TIMES 3 Number of retry attempts
retry.sleep POCKET_RETRY_SLEEP 1000 Retry delay in milliseconds

Testing

To run the SDK's test suite:

composer test

Disclaimer

This is an unofficial SDK for the Pocket API, developed and maintained by Ryan Yannelli. It is not affiliated with, endorsed by, or officially connected to Pocket and Open Vision Engineering Inc any way. Use at your own risk. No warranties or guarantees are provided.

Requirements

  • PHP 8.2 or higher
  • Laravel 12.x

Changelog

Please see CHANGELOG for more information on what has changed recently.

Credits

License

The MIT License (MIT). Please see License File for more information.