Developers

Quickstart

Install the SDK, restore audio in one call, and save the output. Review Diffio API behavior, response fields, setup details, and production workflows.

Restore speech audio by creating a project with your media file, running multiple generations, and downloading results. This quickstart sets your API key, installs the SDK, and walks through each step.

Prerequisites

Before you start, have these ready.

  • A Diffio API key with read and write permissions.
  • A speech focused audio file, for example sample.wav.
  • Python 3.8 or later, or Node 18 or later.

Workflow overview

Projects hold your media. Each project can have multiple generations, often one per model, and you can download each result.

Diffio restoration workflowCreate a project with a media file, run multiple generations with different models, then download the results.Create projectwith mediadiffio-4.5-flashdiffio-4.5-proGenerationsDownload results
A project contains your media. Create multiple generations under it, then download each restored file.

Using the Diffio SDK

  1. 1

    Create an API key

    Create an API key in the developer dashboard and store it as a secret. Pass the key on every request using the Authorization header (X-Api-Key and Xi-Api-Key also work).

    .env
    DIFFIO_API_KEY=diffio_live_...
  2. 2

    Install the SDK

    Install the Diffio SDK for Python or Node, then load the API key from the environment.

    Python
    pip install diffio python-dotenv
    SDK source code

    Browse the SDK repositories on GitHub: diffio-js and diffio-python .

    Upgrading an existing integration

    Diffio 4.5 Flash and Diffio 4.5 Pro are the only models; any other model id is rejected with HTTP 410 and the code model_retired. Upgrade the Python or Node SDK to 0.2.0 or later, which uploads through the Diffio upload API; earlier releases cannot create projects. 0.2.0 has breaking changes, listed in the full API guide.

  3. 3

    Create a project

    Create a file named example.py or example.mjs. Then create a project for your media file. The SDK uploads the file as part of project creation.

    Python
    from dotenv import load_dotenvfrom diffio import DiffioApiError, DiffioClientimport osload_dotenv()client = DiffioClient(apiKey=os.getenv("DIFFIO_API_KEY"))file_path = "sample.wav"project = client.create_project(    filePath=file_path,)
  4. 4

    Run multiple generations

    Create 2 generations, one per current model, so you can compare the results.

    Python
    models = ["diffio-4.5-flash", "diffio-4.5-pro"]generations = []for model in models:    generation = client.create_generation(        apiProjectId=project.apiProjectId,        model=model,        idempotencyKey=f"quickstart-{model}",    )    generations.append({"model": model, "generation": generation})
    Safe retries

    The optional idempotencyKey (1 to 255 characters) makes generation creation safe to retry. Sending the same request again returns the existing generation with idempotentReplay set to true instead of creating and charging a duplicate. Use a different key per model, reusing a key on the same project with a different model returns a 409Conflict, treated as not ready yet. error with code idempotencyKeyConflict.

    Python and Node SDKs automatically retry generation creation only with a nonblank idempotencyKey. Without a key, creation is attempted once, including on network errors, even when maxRetries is enabled. Reuse the same key and request body when retrying an uncertain response.

  5. 5

    Download each result

    Add this block near the end of the file, then poll each generation and download restored audio and any available transcript JSON. Move the node:fs import to the top of the file with the other imports.

    Wait for the overall status to be complete. A stage can reach 100% while the generation is still processing. Diffio 4.5 transcribes the recording before restoration starts, so a complete generation has its transcript.

    Python
    import timefor item in generations:    status = "queued"    while status not in ("complete", "failed"):        progress = client.generations.get_progress(            generationId=item["generation"].generationId,            apiProjectId=project.apiProjectId,        )        status = progress.status        print(item["model"], "status:", status)        if status not in ("complete", "failed"):            time.sleep(5)    if status != "complete":        raise SystemExit(f"Generation failed for {item['model']}")    output_name = f"restored-{item['model']}.mp3"    client.generations.download(        generationId=item["generation"].generationId,        apiProjectId=project.apiProjectId,        downloadFilePath=output_name,        downloadType="mp3",    )    transcript_name = f"transcript-{item['model']}.json"    try:        client.generations.download(            generationId=item["generation"].generationId,            apiProjectId=project.apiProjectId,            downloadFilePath=transcript_name,            downloadType="transcript",        )    except DiffioApiError as exc:        body = exc.responseBody if isinstance(exc.responseBody, dict) else {}        if exc.statusCode == 409 and body.get("code") == "TRANSCRIPT_PENDING":            print("Transcript pending; check progress and retry later.")        elif exc.statusCode == 404 and body.get("code") == "TRANSCRIPT_UNAVAILABLE":            print("Transcript unavailable; restored audio was saved.")        else:            raise
    Transcript availability

    Read progress.transcription.status separately: pending, available, or unavailable. Older responses can omit transcription, so absence does not establish availability. The example tries the transcript download once. If it is pending, poll generation progress and retry the download later if your application needs it.

    Troubleshooting

    If you receive 401Unauthorized, treated as auth error. or 403Forbidden, treated as permission error., confirm the API key is valid and has read and write permissions. A 402Payment required, billing issue such as paymentFailed. API usage can be blocked until billing is updated. error indicates a billing issue: needsPaymentMethod when the $5 starter credit is used up, or cannot cover the file, without a saved payment method, or paymentFailed when a charge failed. API usage is blocked until a payment method is added. A 409Conflict, treated as not ready yet. download error can mean media is still processing or a transcript is pending. Check the error code: transcript requests return TRANSCRIPT_PENDING (409) or TRANSCRIPT_UNAVAILABLE (404).