NEWVectors or files. Pick a path.Start →
    Data Infrastructure
    8 min read
    Updated 2026-07-09

    How to Store TwelveLabs Marengo Embeddings in Your Own Vector Store

    TwelveLabs' async embed API stores Marengo embeddings for only seven days. This guide shows how to persist Marengo video, text, audio, and image embeddings durably in Mixpeek MVS — create a matching namespace, upsert vectors with temporal payloads, and search them — plus when this pattern beats searching inside TwelveLabs itself.

    TwelveLabs
    Marengo
    Video Embeddings
    Vector Store
    BYO Vectors
    MVS

    The Short Answer



    Marengo Embed 2.7 generates multimodal embeddings (video, text, audio, image) through an asynchronous task — the TwelveLabs /embed-v2/tasks endpoint, or twelvelabs.marengo-embed-2-7-v1:0 on Amazon Bedrock — and embeddings created through the async endpoint are stored for seven days. For production reuse you must persist them somewhere durable yourself. A bring-your-own-vectors store like Mixpeek MVS does this in three calls: create a namespace whose vector config matches Marengo's dimension, upsert the embeddings with their temporal metadata as payload, and search. Your embeddings live on object storage you control, alongside vectors from any other model.

    Why persist Marengo embeddings at all?



    Two reasons. Cost: embedding is the expensive step — re-running the async task because the seven-day window lapsed is pure waste. Composition: once the vectors live in a store you control, they stop being TwelveLabs-only. You can filter them by your own metadata, fuse them with text or image embeddings from other models, and serve them to agents — none of which is possible while they exist only inside a task response.

    Step 1: Generate the embeddings



    Use the TwelveLabs SDK or Bedrock. On Bedrock, the async invocation delivers results to S3:
    # Bedrock: StartAsyncInvoke with the Marengo model
    import boto3
    
    bedrock = boto3.client("bedrock-runtime")
    bedrock.start_async_invoke(
        modelId="twelvelabs.marengo-embed-2-7-v1:0",
        modelInput={
            "inputType": "video",
            "mediaSource": {"s3Location": {"uri": "s3://your-bucket/game-footage.mp4"}},
        },
        outputDataConfig={"s3OutputDataConfig": {"s3Uri": "s3://your-bucket/embeddings/"}},
    )
    The response contains one embedding per segment with startSec/endSec markers and an embeddingOption (such as visual-text). Note the vector dimension from your actual response — 1024 for Marengo 2.7 — because the store's config must match it exactly.

    Step 2: Create a matching MVS namespace

    from mixpeek import Mixpeek
    
    client = Mixpeek(api_key="YOUR_API_KEY")
    
    client.namespaces.create(
        namespace_id="marengo-video",
        mode="standalone",
        vector_configs=[
            {"name": "marengo_visual", "dimension": 1024, "metric": "cosine"},
        ],
    )
    MVS can also infer the config from the first write, but declaring it pins the dimension and distance metric explicitly.

    Step 3: Upsert embeddings with temporal payload



    Keep the segment timing and source pointers as payload so search results map back to playable moments:
    client.namespaces.documents.upsert(
        namespace_id="marengo-video",
        documents=[
            {
                "id": "game01-seg-004",
                "vectors": {"marengo_visual": segment["embedding"]},
                "payload": {
                    "video_uri": "s3://your-bucket/game-footage.mp4",
                    "start_sec": segment["startSec"],
                    "end_sec": segment["endSec"],
                    "embedding_option": segment["embeddingOption"],
                },
            }
            for segment in marengo_segments
        ],
    )
    Up to 1,000 documents per request; use bulk import for large backfills.

    Step 4: Search by embedding a query the same way



    Embed the text query with Marengo (text input type), then search — the query and documents must come from the same embedding space:
    results = client.search(
        namespace_id="marengo-video",
        queries=[{
            "vector_name": "marengo_visual",
            "vector": query_embedding,
            "top_k": 10,
        }],
    )
    # each hit returns your payload: video_uri, start_sec, end_sec
    From here you can add metadata filters, BM25 over payload text, or hybrid fusion with vectors from entirely different models — the store does not care who produced each embedding.

    When does this pattern make sense?



    Use TwelveLabs end-to-end when video is your only modality and their hosted index workflow fits: it is the shortest path to high-quality video search, and you skip running a vector store. Add your own store when any of these hold: embeddings must outlive the seven-day task window; content pointers must stay on your object storage; you are fusing Marengo vectors with text, document, or image embeddings from other models; or agents need one queryable surface across everything. The feature-by-feature comparison and alternatives breakdown cover the broader decision; MVS pricing starts at $25/mo on the rate card, and BYO object storage covers running it over your own buckets. For the tool landscape, see best AI video analysis tools.
    Managed Mixpeek

    Put multimodal search to work

    Connect a bucket and Mixpeek runs the whole multimodal search pipeline for you: extraction, indexing, and search over your own objects. No models to wire up, nothing to host.

    Start with Managed
    MVS · bring your own

    Already have vectors?

    Keep your embeddings on your own cloud and run dense, sparse, and BM25 search directly on object storage. From $25/mo.

    Start with MVS

    Run this on your own data

    Point Mixpeek at the storage you already have and search your video, images, audio, and documents the way this guide describes. First 1M vectors included.

    Search your own archive, freeRead Docs