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/"}},
)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"},
],
)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
],
)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_secWhen 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.