Doubleword

    Stop writing boilerplate for batch APIs.

    Get the 50–80% cost savings of provider batch endpoints without rewriting your application logic, managing .jsonl files, or waiting 24 hours for agent loops to finish.

    Try the interactive onboarding

    Sure, you could build it yourself. But should you?

    Writing a script to upload a .jsonl file takes an afternoon. But building a resilient system that handles partial batch failures, routes mixed request types, and manages state across multi-step agent workflows is an ongoing infrastructure tax. Doubleword handles the plumbing so your team can focus on building the actual product.

    Why teams choose Doubleword

    The Autobatcher: Zero-Refactor Savings

    Don't rip out your standard async calls. Our autobatcher acts as a drop-in replacement that transparently collects and batches requests over a configurable window.

    Capture batch-tier pricing instantly without maintaining polling logic or manual parsing.

    Async Inference: Built for Agentic Workflows

    24-hour turnaround times are fine for nightly data dumps, but they completely break multi-stage AI pipelines. Synchronous calls are too expensive for bulk recursive tasks.

    Run complex, chained agent trees and synthetic data pipelines in a single afternoon without paying synchronous premiums.

    Mixed Request Routing: Clean Architecture at Scale

    Don't force your architecture to conform to rigid provider batch rules. Doubleword lets you fire off chat completions, embeddings, and JSON-mode requests in the same batch window.

    We handle the complex parsing and routing under the hood, returning strongly-typed objects exactly where your application expects them.

    Drop-in Ecosystem Compatibility

    Vendor lock-in to a specific provider's batch API creates technical debt. Doubleword offers seamless, unified compatibility.

    Natively supports frameworks like LiteLLM and CrewAI—route to the best models using the orchestration tools you already trust.

    See the difference

    Without Doubleword — ~20 lines
    import json, time, openai
    
    # 1. Build the .jsonl file
    requests = []
    for item in dataset:
        requests.append({
            "custom_id": item["id"],
            "method": "POST",
            "url": "/v1/chat/completions",
            "body": {
                "model": "gpt-4o",
                "messages": [{"role":"user",
                  "content": item["prompt"]}]
            }
        })
    with open("batch.jsonl","w") as f:
        for r in requests:
            f.write(json.dumps(r) + "\n")
    
    # 2. Upload, create batch, poll…
    file = openai.files.create(
        file=open("batch.jsonl","rb"),
        purpose="batch"
    )
    batch = openai.batches.create(
        input_file_id=file.id,
        endpoint="/v1/chat/completions",
        completion_window="24h"
    )
    while batch.status != "completed":
        time.sleep(60)
        batch = openai.batches.retrieve(batch.id)
    
    # 3. Download & parse results
    content = openai.files.content(
        batch.output_file_id)
    results = [json.loads(l)
        for l in content.text.split("\n") if l]
    With Doubleword — 2 lines
    from doubleword import Autobatcher
    
    client = Autobatcher(window="5m")
    
    # That's it. Use it exactly like
    # your existing async client.
    result = await client.chat.completions.create(
        model="qwen3.5-397b-a17b",
        messages=[
            {"role": "user",
             "content": item["prompt"]}
        ]
    )
    
    # Requests are transparently batched,
    # routed, and returned — with an
    # async SLA guarantee.