Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Simplecast Laravel Package

tightenco/simplecast

A Laravel wrapper for the Simplecast podcast hosting API, giving you Eloquent-like models and collections for podcasts, episodes, and analytics. An expressive facade and simple configuration make it easy to pull Simplecast data into any PHP or Laravel application.

View on GitHub
Deep Wiki
Context7

Getting Started

The SDK is intentionally thin: one client class, one API key, methods that map to Simplecast API resources. Treat it as a typed-ish HTTP wrapper rather than a framework.

Install and wire it up

composer require tightenco/simplecast

Get an API key from the Simplecast dashboard (Settings → API), then keep it out of source:

SIMPLECAST_API_KEY=your-key-here

First use case: render a podcast page with episodes

use Simplecast\Simplecast;

$simplecast = new Simplecast(config('services.simplecast.key'));

$podcast  = $simplecast->podcast($podcastId);
$episodes = $simplecast->episodes($podcastId);

In Laravel, register it once in AppServiceProvider so you reuse the underlying HTTP client:

$this->app->singleton(Simplecast::class, fn () =>
    new Simplecast(config('services.simplecast.key'))
);

Where to look first

  1. The README on GitHub — it is short and effectively the API contract.
  2. src/Simplecast.php — the SDK is small enough that the class is the documentation; read the method signatures before assuming endpoint coverage.
  3. Simplecast's own API docs for exact response shapes (the SDK passes payloads through, it does not normalize them into DTOs).

Start with a read-only scenario — fetch podcast metadata and the episode list — before touching write operations.

Implementation Patterns

Wrap the SDK behind your own service. Don't inject Simplecast directly into controllers. A PodcastService that returns arrays or your own DTOs lets you swap the SDK, add caching, and mock it cleanly:

class PodcastService
{
    public function __construct(private Simplecast $simplecast) {}

    public function podcast(string $id): array
    {
        return Cache::remember("simplecast.podcast.$id", now()->addHour(), fn () =>
            $this->simplecast->podcast($id)
        );
    }

    public function episodes(string $podcastId): array
    {
        return Cache::remember("simplecast.episodes.$podcastId", now()->addMinutes(30), fn () =>
            $this->simplecast->episodes($podcastId)
        );
    }
}

Sync to a local table for anything nontrivial. Episode data changes on a schedule you don't control. A scheduled command that upserts into an episodes table gives you search, relationships, ordering, and resilience against API downtime:

// app/Console/Commands/SyncEpisodes.php
public function handle(PodcastService $podcasts): void
{
    foreach ($podcasts->episodes($this->podcastId) as $episode) {
        Episode::updateOrCreate(
            ['simplecast_id' => $episode['id']],
            [
                'title'       => $episode['title'],
                'published_at'=> $episode['published_at'],
                'description' => $episode['description'],
                'audio_url'   => $episode['enclosure_url'] ?? null,
            ],
        );
    }
}

Then schedule it hourly and let the front end read only from the database.

Controller usage via dependency injection:

public function show(PodcastService $podcasts)
{
    return view('podcast.show', [
        'podcast'  => $podcasts->podcast($this->podcastId),
        'episodes' => $podcasts->episodes($this->podcastId),
    ]);
}

Testing. Never hit the live API in tests. Bind a fake in the container:

$this->mock(Simplecast::class, function ($mock) {
    $mock->shouldReceive('episodes')->andReturn([['id' => 'abc', 'title' => 'Pilot']]);
});

Write operations (if you use them). Create/update/delete calls return the created resource; capture the ID and persist it locally immediately so you're not re-fetching to reconcile.

Gotchas and Tips

No Laravel auto-discovery. There is no service provider, facade, or config file shipped. You must bind it yourself. Forgetting this and calling new Simplecast(...) inline in several places means several HTTP clients and several places to update config.

Not everything is covered. The SDK is a convenience wrapper, not a complete client. If a Simplecast endpoint is missing, drop to raw Guzzle/HTTP against the same base URL and bearer token rather than forking the package. Check src/Simplecast.php before assuming a method exists — the API changes more often than the SDK does.

Responses are associative arrays, not objects. Access with $episode['id'], not $episode->id, and don't assume keys exist — guard optional fields like enclosure_url with ??. Shapes vary between endpoints.

IDs are opaque strings. Casting them to integers or assuming numeric IDs will break. Store as strings (often UUID-ish), use string columns in your migrations.

Errors throw. Non-2xx responses raise exceptions, not null returns. Catch around user-triggered calls:

try {
    $episode = $this->simplecast->episode($episodeId);
} catch (Throwable $e) {
    report($e);
    abort(404);
}

404 for missing episodes and 429 for rate limiting are the two you'll actually hit. Handle 429 with caching plus an exponential backoff retry rather than hammering the API.

Paginate deliberately. Episode collections come back paginated. Check the default page size and the pagination structure in the response — a podcast with hundreds of episodes is the classic case of silently truncating your list. Loop or request explicit pages.

Cache aggressively but pick the TTL by endpoint. Podcast metadata changes rarely (hour-plus); the newest episode can appear at any publish time (minutes). If you need "show the newest episode within five minutes," cache the podcast object longer than the episode list.

Configure timeouts and retries. The SDK wraps an HTTP client; a hung Simplecast call should not hang your web request. If the client isn't injectable, keep SDK calls off the request path entirely — that's the strongest argument for the sync-to-database pattern.

Keep the key server-side only. Never expose it to the browser; if you need client-side episode rendering, proxy through a Laravel route or read from your synced table.

Watch for breaking API drift. Because the SDK is thin and rarely updated, a Simplecast API change can surface as a missing array key rather than an exception. The local-table sync pattern insulates you: validate on ingest and log when expected keys are absent.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle