> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zespan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pinecone

> Auto-trace Pinecone query and upsert calls with zespan.autopatch() — retrieval spans and RAG context capture with no code changes to your Pinecone client calls.

<Note>
  Available for: **Python** and **TypeScript**.
</Note>

Calling Pinecone directly (no LangChain/LlamaIndex retriever abstraction in between) previously got zero automatic tracing — only the manual `recordRetrieval`/`record_retrieval` helper. Zespan now patches Pinecone's `Index` client so every `query()` and `upsert()` call is captured automatically, the same way LLM provider calls already are.

<Note>
  Patched automatically as part of `zespan.autopatch()`, which both SDKs run on `init()` unless you pass `autopatch: false` (`autopatch=False` in Python). There's no separate opt-in call for vector-DB tracing.
</Note>

## What gets traced

* **Reads** — `index.query()` (sync) and the async client's `query()` emit a `retriever` span
* **Writes** — `index.upsert()` (sync and async) emits an `embedding` span

<Tabs>
  <Tab title="Python">
    ### Installation

    ```bash theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    pip install zespan pinecone
    ```

    ### Usage

    ```python theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    import zespan

    zespan.init(api_key="zsp_your_api_key_here")  # patches Pinecone automatically

    from pinecone import Pinecone

    pc = Pinecone(api_key="pc_your_api_key_here")
    index = pc.Index("my-index")

    # Traced automatically -- emits a "retriever" span
    results = index.query(vector=query_embedding, top_k=5, include_metadata=True)

    # Traced automatically -- emits an "embedding" span
    index.upsert(vectors=[
        {"id": "doc1", "values": doc_embedding, "metadata": {"text": "chunk text", "source": "handbook.pdf"}},
    ])
    ```

    <Note>
      `AsyncIndex` (Pinecone's async client) is patched the same way — `await index.query(...)` and `await index.upsert(...)` are traced identically to the sync calls above.
    </Note>
  </Tab>

  <Tab title="TypeScript">
    ### Installation

    ```bash theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    npm install @zespan/sdk @pinecone-database/pinecone
    ```

    ### Usage

    ```typescript theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
    import { zespan } from "@zespan/sdk";

    zespan.init({ apiKey: process.env.ZESPAN_API_KEY! }); // patches Pinecone automatically

    import { Pinecone } from "@pinecone-database/pinecone";

    const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });
    const index = pc.index("my-index");

    // Traced automatically -- emits a "retriever" span
    const results = await index.query({ vector: queryEmbedding, topK: 5, includeMetadata: true });

    // Traced automatically -- emits an "embedding" span
    await index.upsert({
      records: [
        { id: "doc1", values: docEmbedding, metadata: { text: "chunk text", source: "handbook.pdf" } },
      ],
    });
    ```

    <Note>
      The `Index` class's prototype is patched once at import time — every index instance you create (`pc.index(...)`) is traced, not just one.
    </Note>
  </Tab>
</Tabs>

## What gets captured

### Read span (`query()`) — `span_kind: "retriever"`, `operation: "vector_search"`

| Field                   | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider`              | `"pinecone"`                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `latency_ms`            | Time spent in the real `query()` call                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `status`                | `"success"` or `"error"` (with `error_message`, truncated to 500 characters)                                                                                                                                                                                                                                                                                                                                                                                     |
| `rag_context_count`     | Number of matches returned                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `metadata.rag_contexts` | One entry per match: `{ content, document_id, score, source }` — `content` comes from the match's metadata (its text field), `document_id` from the match id, `score` from the match's similarity score. Same shape [`recordRetrieval`/`record_retrieval`](/sdk/manual-spans#recording-retrieved-documents) produces, so the trace-detail **Retrieval** panel and the [RAG evaluators](/dashboard/evaluations#evaluating-rag-pipelines) work with no extra setup |
| `metadata.top_k`        | Requested result count, read from the call's `top_k`/`topK` option. Always recorded — not gated by `storePrompts`, since it's a count, not query content. (The ingest pipeline only persists the `metadata` object verbatim, so this field is only ever observable nested under `metadata`, not as a bare top-level field.)                                                                                                                                      |
| `metadata.filter`       | The query's `filter` option, redacted and stringified — only present when `storePrompts`/`store_prompts` is `true` (its default). Filter values commonly carry user IDs, emails, or other PII, so unlike `top_k` this is dropped entirely, not just redacted, when `storePrompts` is off. (Same `metadata`-only visibility as `top_k` above.)                                                                                                                    |

`content` follows your `storePrompts`/`store_prompts` setting and the same redaction rules as prompt text — set `storePrompts: false` and match text is dropped while `document_id`/`source`/`score` are still kept.

### Write span (`upsert()`) — `span_kind: "embedding"`, `operation: "vector_upsert"`

| Field                   | Details                                                                                                                                                                                   |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider`              | `"pinecone"`                                                                                                                                                                              |
| `metadata.vector_count` | Number of vectors in the upsert call. Only observable nested under `metadata` — the ingest pipeline persists the `metadata` object verbatim but drops other unrecognized top-level fields |
| `latency_ms`            | Time spent in the real `upsert()` call                                                                                                                                                    |
| `input_tokens`          | Always `0` — the wrapper doesn't generate embeddings, it only records that vectors already computed elsewhere were upserted                                                               |
| `status`                | `"success"` or `"error"` (with `error_message`)                                                                                                                                           |

<Warning>
  **Linking a Pinecone query to a following LLM call.** Trace context (`trace_id`) is picked up from whatever `with_zespan_context()`/`withZespanContext()` scope is active when `query()`/`upsert()` runs — the same rule every other Zespan wrapper follows. If your Pinecone call and your LLM call are two independent, unwrapped top-level calls, they land on **two different traces**, and RAG evaluators/the Retrieval panel won't see the connection between them. Wrap both in the same `with_zespan_context()`/`withZespanContext()` block, exactly like the [complete RAG pipeline example](/sdk/manual-spans#complete-rag-pipeline-example) in Manual spans.
</Warning>

## Next steps

* [Manual spans](/sdk/manual-spans) — the `record_vector_search()`/`recordVectorSearch()` helper for pgvector, and the full `with_zespan_context()`/`withZespanContext()` trace-linking pattern
* [Evaluating RAG pipelines](/dashboard/evaluations#evaluating-rag-pipelines) — score retrieval quality once `rag_contexts` is on the trace
* [Chroma](/sdk/integrations/chroma), [Weaviate](/sdk/integrations/weaviate), [Qdrant](/sdk/integrations/qdrant) — the other auto-traced vector DBs
