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

Assemblyai Laravel Laravel Package

alex-volga/assemblyai-laravel

A Laravel wrapper for the AssemblyAI speech-to-text API, making audio and video transcription easy to configure and use from your PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

The package wraps a speech-to-text API (AssemblyAI-style) behind a Laravel facade, so the entry points are small and predictable.

  1. Install and configure:

    composer require <vendor>/<package>
    php artisan vendor:publish --tag=<package>-config
    

    Then set the API key in .env (typically ASSEMBLYAI_API_KEY or the package's own key name). Confirm the key is read from config/...php, not directly via env() in your own code — env() returns null once config is cached.

  2. Where to look first: the TranscriptParams builder documentation. This is the single object that governs every transcription option (speech model, language, diarization, audio intelligence, PII redaction, prompts, word boosting). Read it before writing any transcription code — it saves a rewrite later.

  3. First use case — transcribe a local or remote file asynchronously:

    use Vendor\Package\Facades\Transcription;
    
    $transcript = Transcription::transcripts()->create(
        TranscriptParams::make()
            ->audioUrl(Storage::disk('s3')->url($path))
            ->speechModel('best')
            ->language('en')
    );
    
    // $transcript->id is what you persist; the job is not done yet.
    

    Note the method name: create, not submit. v1.0.1 corrected a documentation typo here, so older snippets you find in blog posts and gists may still show submit.

  4. Persist the returned transcript ID immediately, dispatch a queued poll or register a webhook, and only then treat the request as "done". Nothing in this package blocks until the transcript is ready.

Implementation Patterns

Wrap transcription in a job, never in a controller. Upload + request is fast; waiting is not. A two-job pattern works well:

TranscribeAudio::dispatch($audio);        // calls transcripts()->create, stores ID
PollTranscript::dispatch($transcriptId)->delay(now()->addSeconds(15));

Prefer webhooks over polling where the package supports them. Polling is the fallback for local development (where the provider cannot reach your machine) — gate it with app()->isLocal() so production does not burn requests.

Centralise params in a config or a named constructor. Because TranscriptParams exposes a large surface (models, diarization, PII, prompts, word boosting), teams quickly end up with copy-pasted builders that drift. Use one of:

// config/transcription.php
'presets' => [
    'podcast' => ['speech_model' => 'best', 'diarization' => true],
    'support_call' => ['pii_redaction' => true, 'word_boost' => ['order id', 'refund']],
],

and a small factory that maps a preset name onto the builder. That gives you one place to change defaults when the provider ships a new model.

Model the transcript as a local record, not a remote one. Create a transcripts table with external_id, status, language, duration, raw_response (json), and index external_id. The package will hand you a DTO; persist it. You do not want to re-fetch a completed transcript to render a page.

Feature toggles belong per-request, not globally. Diarization, PII redaction and audio intelligence all change output shape and price. Set them on the builder for the specific use case rather than in the package config, so a cheap bulk import does not silently inherit an expensive interactive preset.

Word boosting is your accuracy lever. For domain vocabulary (product names, internal jargon, surnames) pass a wordBoost array of a few dozen terms. It is far cheaper than switching to a heavier model and often fixes the specific words users complain about.

Queue + retry semantics. Transcription calls are idempotent-ish only if you keep the ID. Give the create job $tries = 3 with backoff, and the poll job a $maxExceptions-style budget so a stuck transcript does not poll forever — mark it failed after a bounded number of attempts and surface that in your UI.

Gotchas and Tips

  • create vs submit. The v1.0.1 typo fix means some tutorials are wrong. If you get a "method does not exist" error, check the actual signature via php artisan tinker or reflection before assuming a version mismatch.

  • Everything is asynchronous. transcripts()->create() returns immediately with status = queued (or processing). Code that reads ->text straight after create() gets null. Guard your accessors.

  • Parameter casing differs from method names. The builder's fluent methods are camelCase but the wire format is snake_case. If you switch from fluent calls to an array, do not assume the keys match. Log the outgoing payload once during integration — it is the fastest way to confirm diarization/PII flags actually reached the provider.

  • Language selection interacts with model choice. Some speech models only support a subset of languages, and forcing a language on a model that does not support it can produce an error or degraded output rather than a fallback. Test your language/model pair explicitly; do not assume language('auto') is free.

  • Diarization changes the response shape. With it enabled, you get utterances/speaker labels rather than a flat text blob. Write your parser against the diarized shape if you enable it anywhere, or normalise immediately on ingestion into your own segments structure.

  • PII redaction is destructive and priced. Redacted output cannot be recovered from that transcript. If you might need the raw text later (audit, dispute, model fine-tuning), either run two transcripts or store the unredacted version under stricter access controls.

  • Config caching bites. After php artisan config:cache, env() calls outside config files return null — a classic "works locally, fails in staging" cause for missing API keys.

  • Debugging checklist when a transcript never completes: (1) confirm the audio URL is publicly reachable by the provider (signed S3 URLs with short TTLs expire mid-job), (2) check the stored status and any error field on the transcript record, (3) log the raw response body, not just the DTO, (4) verify your queue worker has not timed out.

  • Extension points worth knowing. The config file usually lets you swap the HTTP client/transport and set a base URI — useful for pointing at a mock server in tests so your suite never calls the real API. Wrap calls in Http::fake() (or the package's equivalent) in feature tests; assert on the outgoing payload rather than just the response.

  • Pin the version. v1.0.1 is documentation-only, so upgrading is safe, but treat the TranscriptParams surface as the stability boundary: it changed shape in the past and will again. A ^1.0 constraint plus a test that constructs your most complex builder is cheap insurance.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin