Index¶
Obtain an Index instance via pinecone.Pinecone.index().
from pinecone import Pinecone
pc = Pinecone(api_key="your-api-key")
# Resolve host automatically by index name
idx = pc.index("my-index")
# — or — connect directly with a host URL
idx = pc.index(host="my-index-abc123.svc.pinecone.io")
Method groups:
Vectors —
upsert(),upsert_from_dataframe(),upsert_records(),query(),query_namespaces(),fetch(),fetch_by_metadata(),update(),delete(),list(),list_paginated()Stats —
describe_index_stats()Documents —
documents, a lazily-instantiatedDocumentsnamespace for schema-based indexes (index.documents.upsert,.search,.fetch,.delete,.update,.list,.batch_upsert).Integrated Inference —
search(),search_records()Namespaces —
create_namespace(),describe_namespace(),delete_namespace(),list_namespaces(),list_namespaces_paginated()Bulk Import —
start_import(),describe_import(),cancel_import(),list_imports(),list_imports_paginated()
- class pinecone.index.Index(*, host, api_key=None, additional_headers=None, timeout=30.0, proxy_url=None, proxy_headers=None, ssl_ca_certs=None, ssl_verify=True, source_tag=None, connection_pool_maxsize=0, **kwargs)[source]¶
Bases:
objectSynchronous data plane client targeting a specific Pinecone index.
An index’s data plane is where its records live, and this is the client that reads and writes them. Reach one with
pc.index(name="article-search"), or construct it here from a host URL when you already know the host and want to skip the describe-index lookup that resolving a name costs. Every call blocks;AsyncIndexis theasynciotwin.Only errors specific to a single method are documented on that method. For the exception hierarchy every method shares, see Error Handling.
- Parameters:
host (str) – The index-specific data plane host URL.
api_key (str | None) – Pinecone API key. Falls back to
PINECONE_API_KEYenv var.additional_headers (Mapping[str, str] | None) – Extra headers included in every request.
timeout (float) – Request timeout in seconds. Defaults to
30.0.proxy_url (str | None) – HTTP proxy URL for outgoing requests.
ssl_ca_certs (str | None) – Path to a CA certificate bundle for SSL verification.
ssl_verify (bool) – Whether to verify SSL certificates. Defaults to
True.source_tag (str | None) – Tag appended to the User-Agent string for request attribution.
connection_pool_maxsize (int) – Maximum number of connections to keep in the pool.
0(default) uses httpx defaults.pool_threads (int | None) – Tune the thread pool used by the legacy
async_req=Trueexecution model onupsert,query,describe_index_stats, andlist_paginated. Defaults to10. The pool is lazy-constructed on firstasync_req=Truecall and shut down byclose();multiprocessing.poolis not imported until then. For new code, preferAsyncIndexorconcurrent.futures.ThreadPoolExecutor. This kwarg exists for backcompat with pre-rewrite callers.kwargs (Any)
- Raises:
PineconeValueError – If no API key can be resolved or the host is invalid.
FileNotFoundError – If
ssl_ca_certsnames a path that does not exist, raised when the client is constructed, so a mistyped path cannot leave you silently verifying against the default trust store instead. A bundle that exists but cannot be parsed as a certificate raisesssl.SSLErrorinstead.
Examples
>>> from pinecone import Pinecone >>> pc = Pinecone(api_key="your-api-key") >>> idx = pc.index(name="article-search") >>> idx.describe_index_stats().total_vector_count 0
See also
AsyncIndex— the same surface onasyncio.GrpcIndex— the gRPC transport, for write-heavy ingest.- __init__(*, host, api_key=None, additional_headers=None, timeout=30.0, proxy_url=None, proxy_headers=None, ssl_ca_certs=None, ssl_verify=True, source_tag=None, connection_pool_maxsize=0, **kwargs)[source]¶
- property documents: Documents¶
Entry point for document operations on a schema-based index.
A schema-based index stores JSON records instead of raw vectors. Reach the document operations —
upsert,search,fetchand the rest — through here; the vector methods on this class (upsert(),query()) are for a vector-based index. The same instance is returned on every access.- Returns:
Documentsnamespace instance.
Examples
>>> from pinecone import Pinecone >>> pc = Pinecone(api_key="your-api-key") >>> idx = pc.index(name="article-search") >>> response = idx.documents.upsert( ... namespace="published", ... documents=[{"_id": "article-101", "title": "Intro to vectors"}], ... ) >>> response.upserted_count 1
See also
Documents— every document operation, with an example each.
- upsert(*, vectors, namespace='', batch_size=None, show_progress=True, max_concurrency=8, timeout=None, total_timeout=None)[source]¶
Upsert a batch of vectors into a namespace.
If a vector with the same ID already exists in the namespace, it is overwritten.
Each request is capped on both vector count and encoded payload size; wide vectors or large metadata tend to hit the size cap first. Pass
batch_sizeto split a long sequence of vectors into requests that stay under both limits.- Parameters:
vectors (Sequence[Vector | tuple[str, Sequence[float]] | tuple[str, Sequence[float], Mapping[str, Any]] | Mapping[str, Any]]) – Sequence of vectors to upsert. Each element can be a
Vector, a tuple of(id, values)or(id, values, metadata), or a dict withid,values, and optionalsparse_values/metadatakeys.namespace (str) – Target namespace, e.g.
"articles-en". Defaults to the empty string, which addresses the index’s default namespace.batch_size (int | None) – Split vectors into chunks of this size and send one request per chunk, e.g.
100.None(default) sends every vector in one request. Must be a positive integer.show_progress (bool) – When
True(default) andtqdmis installed, display a progress bar that advances as batches complete. No effect whenbatch_sizeisNoneortqdmis not installed.max_concurrency (int) – Batch requests in flight at once, 1-64. Defaults to
8. Only used whenbatch_sizeis set.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
total_timeout (float | None) – Deadline in seconds for the whole batched operation, as opposed to timeout, which bounds one attempt of one batch. On expiry no further batches are submitted; batches already in flight are awaited and never cancelled; unsent batches are reported in
failed_items.None(default) means no deadline.
- Returns:
UpsertResponsewithupserted_count. Whenbatch_sizetriggers multiple requests,response_infocarries the aggregate LSN from all successful batches, orNoneif no LSN headers came back, anderrors/failed_itemsname whatever did not land.- Raises:
PineconeTypeError – If a vector element is not one of the forms listed above.
PineconeValueError – If a vector element is malformed, batch_size is not a positive integer, or max_concurrency falls outside 1-64.
ApiError – If one request exceeds the server’s cap on vectors per request or on encoded request size — lower
batch_sizeand retry.
- Return type:
Examples
All three vector forms are interchangeable within one call. The values below are truncated to three floats for the page; pass your index’s full dimension.
>>> from pinecone import Vector >>> idx = pc.index(name="article-search") >>> response = idx.upsert( ... vectors=[ ... Vector(id="article-101", values=[0.012, -0.087, 0.153]), ... ("article-102", [0.045, 0.021, -0.064]), ... {"id": "article-103", "values": [0.091, -0.032, 0.178]}, ... ], ... namespace="articles-en", ... ) >>> response.upserted_count 3
For a sequence too long for one request —
embeddingsbelow being your whole list of vectors — setbatch_sizeand check the response for batches that did not land:response = idx.upsert( vectors=embeddings, namespace="articles-en", batch_size=100, ) if response.has_errors: idx.upsert(vectors=response.failed_items, namespace="articles-en")
Note
With
batch_sizeset, batches are submitted in parallel through aThreadPoolExecutorofmax_concurrencyworkers, and a partial failure does not raise —response.has_errors,response.errorsandresponse.failed_itemsreport it, andfailed_itemscan be passed straight back toupsert. Each batch is retried on its own under the client’s retry policy, timeouts included, so timeout bounds one attempt rather than the batch; see Retries and Resilience.See also
upsert_records()— text in, embedded server-side, for an index with integrated inference.upsert_from_dataframe()— the same write from a pandas DataFrame, batched for you.start_import()— millions of vectors from cloud storage, server-side and asynchronous.
- upsert_from_dataframe(df, namespace=None, batch_size=500, show_progress=True, timeout=None, *, max_concurrency=None, total_timeout=None, on_error=None)[source]¶
Upsert vectors from a pandas DataFrame.
Convenience method that accepts a DataFrame with columns
id,values, and optionallysparse_valuesandmetadata, batches the rows, and upserts them viaupsert().- Parameters:
df (pd.DataFrame) – A
pandas.DataFramewith at leastidandvaluescolumns.sparse_valuesandmetadatacolumns are included when present and non-None.namespace (str | None) – Target namespace, e.g.
"articles-en". Defaults to the index’s default namespace.batch_size (int) – Number of rows per upsert batch. Defaults to 500.
show_progress (bool) – If
True(default) andtqdmis installed, display a progress bar that advances as batches complete. Iftqdmis not installed, silently falls back to no progress bar.timeout (float | None) – Client-side request timeout in seconds applied to each batch’s upsert request — not to the DataFrame as a whole.
None(default) uses the client-level default. Raise it to accommodate large or slow batches.max_concurrency (int | None) – Number of batches in flight at once, range
[1, 64].None(default) uses8— flat and identical across every transport. The host’s adaptive limit still applies underneath.total_timeout (float | None) – Deadline in seconds for the whole ingest, as opposed to timeout, which bounds a single attempt of a single batch. On expiry no further batches are submitted; batches already in flight are awaited and never cancelled; unsent batches are reported in
failed_items.None(default) means no deadline.on_error (Literal['raise', 'collect'] | None) – What to do when some batches fail.
"collect"(the default) returns anUpsertResponsecarryingfailed_item_count,errorsandfailed_items."raise"re-raises the lowest-indexed batch failure once every batch has settled, with the partial result attached to the exception’sresponseattribute.
- Returns:
UpsertResponsewithupserted_counttotalled across every batch that landed.- Raises:
RuntimeError – If
pandasis not installed. It is not an SDK dependency; install it yourself withpip install pandas.PineconeValueError – If df is not a
pandas.DataFrame, batch_size is not a positive integer, or max_concurrency falls outside 1-64.PineconeTimeoutError – If
on_error="raise"and a batch exhausted its retries on timeout. Under the defaulton_error="collect"that same failure is reported on the returned response rather than raised.
- Return type:
Examples
A
metadatacolumn is optional; where it is present its dict lands on the vector as written.import pandas as pd from pinecone import Pinecone pc = Pinecone(api_key="your-api-key") idx = pc.index(name="article-search") df = pd.DataFrame([ { "id": "article-101", "values": [0.012, -0.087, 0.153], "metadata": {"topic": "science", "year": 2024}, }, { "id": "article-102", "values": [0.045, 0.021, -0.064], "metadata": {"topic": "technology", "year": 2024}, }, ]) response = idx.upsert_from_dataframe( df, namespace="articles-en", batch_size=100, ) print(response.upserted_count)
Note
pandasis not an SDK dependency — this is the only method that needs it, so install it in your own environment.See also
upsert()— the same write from a list of vectors, with the samebatch_sizeand nopandasdependency.upsert_records()— text in, embedded server-side, for an index with integrated inference.start_import()— millions of vectors from cloud storage, server-side and asynchronous.
- upsert_records(*, records, namespace, timeout=None)[source]¶
Upsert records for indexes with integrated inference.
Records are sent as newline-delimited JSON (NDJSON). Embeddings are generated server-side.
- Parameters:
records (list[dict[str, Any]]) – Record dicts, each carrying an
_id(orid) plus the fields to store; the index’s embedding model decides which field it embeds. A record giving both_idandidkeeps_idand the client drops theidbefore sending.namespace (str) – Target namespace, e.g.
"articles-en". Required and non-empty — unlikeupsert(), the records API has no default namespace to fall back on.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
UpsertRecordsResponsewithrecord_count, the number of records submitted.- Raises:
PineconeValueError – If namespace is not a non-empty string, records is empty, or a record has no
_id/idfield or one that is not a string. Raised before any HTTP request is made.- Return type:
Examples
>>> idx = pc.index(name="article-search") >>> response = idx.upsert_records( ... namespace="articles-en", ... records=[ ... {"_id": "article-101", "text": "Vector databases for search."}, ... {"_id": "article-102", "text": "RAG combines search with LLMs."}, ... ], ... ) >>> response.record_count 2
See also
search()— the read side of an integrated-inference index: text in, embedded server-side.upsert()— for an index where you embed the text yourself and send vectors.start_import()— millions of vectors from cloud storage, server-side and asynchronous.
- query(*, top_k, vector=None, id=None, namespace='', filter=None, include_values=False, include_metadata=False, sparse_vector=None, scan_factor=None, max_candidates=None, timeout=None)[source]¶
Query a namespace for the nearest neighbours of a vector you supply.
You supply the query vector; nothing is embedded for you. At least one query selector is required: a dense vector, a sparse_vector, both together for a hybrid query, or the id of a vector the index already holds. An id is a reference to stored data, so it cannot be mixed with either vector form.
- Parameters:
top_k (int) – Number of results to return, 1-10000, e.g.
5.vector (list[float] | None) – Dense query vector, at your index’s dimension.
id (str | None) – ID of a stored vector to use as the query, e.g.
"article-101". Cannot be combined with vector or sparse_vector.namespace (str) – Namespace to query, e.g.
"articles-en". Defaults to the index’s default namespace.filter (dict[str, Any] | None) – Metadata filter expression restricting which vectors are searched, e.g.
{"year": {"$gte": 2020}}.include_values (bool) – Return each match’s vector values.
False(default) keeps the response small.include_metadata (bool) – Return each match’s metadata. Set it when you need the fields you filtered on back in the result.
sparse_vector (SparseValues | dict[str, Any] | None) – Sparse query vector with indices and values. Can be combined with vector for a hybrid query on indexes that support both.
scan_factor (float | None) – Recall/latency trade for dedicated read node (DRN) indexes — a multiplier on how much of the index is scanned. Above 1 scans more and favours recall; below 1 scans less and favours latency. Omit to let the server choose.
max_candidates (int | None) – Recall/latency trade for dedicated read node (DRN) indexes — caps how many candidates are reranked before
top_kis taken. Must be at leasttop_k: a smaller value is rejected rather than clamped, since it could not fill the page.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
QueryResponsewithmatches(ordered from most to least similar, each carryingidandscore),namespace, andusage.- Raises:
PineconeValueError – If top_k falls outside 1-10000, if id is combined with vector or sparse_vector, if none of vector, id, or sparse_vector is given, or if id is not a legal vector ID. Raised before any HTTP request is made.
ApiError – If scan_factor or max_candidates is out of range, or the index is not a dense DRN index — both knobs are rejected on on-demand indexes and on sparse indexes.
- Return type:
Examples
Query vectors are truncated to three floats on this page; pass your index’s full dimension.
>>> idx = pc.index(name="product-search") >>> response = idx.query( ... top_k=2, ... vector=[0.012, -0.087, 0.153], ... namespace="electronics", ... ) >>> [(match.id, match.score) for match in response.matches] [('prod-0', 0.9), ('prod-1', 0.8)]
A match comes back stripped by default, and the two flags are not symmetric about it — an unrequested
valuesis empty, an unrequestedmetadataisNone:>>> response.matches[0].values [] >>> response.matches[0].metadata is None True
Ask, and both arrive. A
filternarrows the search before ranking, soinclude_metadatais how you see the fields you selected on:>>> response = idx.query( ... top_k=2, ... vector=[0.012, -0.087, 0.153], ... namespace="electronics", ... filter={"category": {"$eq": "audio"}}, ... include_metadata=True, ... ) >>> response.matches[0].metadata["description"] 'Noise-cancelling over-ear headphones 0'
See also
search()— the same search on an integrated-inference index: you pass text, the server embeds it.documents—documents.searchfor a schema-based index, which stores JSON records rather than raw vectors.query_namespaces()— the same query fanned out over several namespaces, merged into one ranking.
- query_namespaces(*, vector=None, namespaces, metric, top_k=None, filter=None, include_values=False, include_metadata=False, sparse_vector=None, scan_factor=None, max_candidates=None, timeout=None)[source]¶
Query several namespaces at once and merge them into one ranking.
One
query()per namespace, issued in parallel on a thread pool of up to 32 workers, then merged so the result is the overall top-k rather than top-k per namespace. Because the merge ranks by metric, you have to name the index’s metric yourself — nothing here reads it off the index.- Parameters:
vector (Sequence[float] | None) – Dense query vector values. Required for dense and hybrid indexes; omit for sparse-only indexes (use sparse_vector instead).
namespaces (Sequence[str]) – Namespaces to query, e.g.
["articles-en", "articles-fr"]. Must be non-empty; duplicates are removed while preserving order.metric (str) – Distance metric the merge ranks by —
"cosine","euclidean", or"dotproduct". Pass the metric the index was created with, or the merged ranking will be wrong.top_k (int | None) – Maximum number of results to return after merging, e.g.
10. Defaults to 10. Each namespace is queried for this many, so the merge chooses fromtop_k × len(namespaces)candidates.filter (Mapping[str, Any] | None) – Metadata filter expression applied to every namespace.
include_values (bool) – Return each match’s vector values.
include_metadata (bool) – Return each match’s metadata.
sparse_vector (SparseValues | Mapping[str, Any] | None) – Sparse query vector with indices and values. Required for sparse-only indexes when vector is omitted.
scan_factor (float | None) – Recall/latency trade for dedicated read node (DRN) indexes — a multiplier on how much of the index is scanned. Above 1 scans more and favours recall; below 1 scans less and favours latency. Applied to every namespace queried.
max_candidates (int | None) – Recall/latency trade for dedicated read node (DRN) indexes — caps how many candidates are reranked before
top_kis taken, per namespace. Must be at leasttop_k.timeout (float | None) – Per-request timeout in seconds, applied to each namespace’s query rather than to the fan-out as a whole.
- Returns:
QueryNamespacesResultswith the mergedmatches,usagetotalled over every namespace, andns_usagekeyed by namespace name. A match carries no record of which namespace produced it, so query one namespace at a time when you need that.- Raises:
PineconeValueError – If namespaces is empty, if both vector and sparse_vector are absent or empty, or if metric is not one of
"cosine","euclidean", or"dotproduct". Raised before any HTTP request is made.ApiError – If any one namespace’s query fails; the first such failure propagates and the merged result is lost, so retry the whole call.
- Return type:
Examples
The query vector is truncated to three floats on this page; pass your index’s full dimension.
results = idx.query_namespaces( vector=[0.012, -0.087, 0.153], namespaces=["articles-en", "articles-fr", "articles-de"], metric="cosine", top_k=10, ) for match in results.matches: print(match.id, match.score)
On a sparse-only index, pass sparse_vector instead and rank by
"dotproduct":results = idx.query_namespaces( sparse_vector={"indices": [17, 42, 108], "values": [0.4, 0.9, 0.2]}, namespaces=["docs-en", "docs-fr"], metric="dotproduct", top_k=10, )
See also
query()— one namespace, and the place every argument here is documented in full.
- fetch(*, ids, namespace='', timeout=None)[source]¶
Fetch vectors by their IDs, exactly as stored.
A lookup, not a search: nothing is ranked and no score is returned. An ID that is not in the namespace is silently absent from the result, so compare the keys you got back against the ones you asked for.
- Parameters:
ids (list[str]) – Vector IDs to fetch, e.g.
["article-101", "article-102"]. Must be non-empty, and every ID must be 1-512 ASCII characters without a NUL.namespace (str) – Namespace to fetch from, e.g.
"articles-en". Defaults to the index’s default namespace.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
FetchResponsewithvectors, a map of ID toVectorholding values and metadata as stored, plusnamespaceandusage. IDs the namespace does not hold are absent from the map rather than raising.- Raises:
PineconeValueError – If ids is empty or holds an ID that is not 1-512 ASCII characters without a NUL. Raised before any HTTP request is made.
- Return type:
Examples
wanted = ["article-101", "article-102"] response = idx.fetch(ids=wanted, namespace="articles-en") for vid, vec in response.vectors.items(): print(vid, vec.metadata) print("not in this namespace:", set(wanted) - set(response.vectors))
See also
fetch_by_metadata()— when you know the metadata you want rather than the IDs.query()— when you want the nearest vectors rather than named ones.
- fetch_by_metadata(*, filter, namespace='', limit=None, pagination_token=None, timeout=None)[source]¶
Fetch one page of the vectors whose metadata matches a filter.
A lookup, not a search: matches are not ranked and carry no score. One page is returned per call, so follow
pagination.nextto reach the rest — see Pagination.- Parameters:
filter (dict[str, Any]) – Metadata filter expression, e.g.
{"year": {"$gte": 2020}}. Must carry at least one condition; an empty filter is rejected rather than treated as “match everything”.namespace (str) – Namespace to fetch from, e.g.
"movies-en". Defaults to the index’s default namespace.limit (int | None) – Maximum number of vectors in this page, 1-10000. Omit to let the server choose the page size.
pagination_token (str | None) –
pagination.nextfrom the previous response.None(default) fetches the first page.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
FetchByMetadataResponsewithvectorsas stored, plusnamespace,usage, andpaginationwhosenextis the token for the following page orNoneon the last one.- Raises:
PineconeValueError – If filter is empty or limit falls outside 1-10000. Raised before any HTTP request is made.
- Return type:
Examples
response = idx.fetch_by_metadata( filter={"genre": "comedy", "year": {"$gte": 2020}}, namespace="movies-en", ) for vid, vec in response.vectors.items(): print(vid, vec.metadata)
See also
fetch()— when you already know the IDs.query()— when you want the nearest vectors to a query rather than every vector a filter admits.Pagination — walking every page.
- delete(*, ids=None, delete_all=False, filter=None, namespace='', timeout=None)[source]¶
Delete vectors from a namespace by ID, by filter, or all of them.
Exactly one selector: ids, filter, or
delete_all=True. The delete is irreversible and IDs the namespace does not hold are ignored rather than reported, so a successful call is not evidence anything was deleted.- Parameters:
ids (list[str] | None) – Vector IDs to delete, e.g.
["article-101", "article-102"]. Every ID must be 1-512 ASCII characters without a NUL.delete_all (bool) – Delete every vector in namespace. The namespace itself survives;
delete_namespace()removes that too.filter (dict[str, Any] | None) – Metadata filter expression selecting what to delete, e.g.
{"status": {"$eq": "retracted"}}. Must carry at least one condition, and cannot be combined with ids — see the note below.namespace (str) – Namespace to delete from, e.g.
"articles-en". Defaults to the index’s default namespace.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
None — a successful delete returns no payload.
- Raises:
PineconeValueError – If zero or more than one selector is given, if filter is empty, or if an ID is not legal. Raised before any HTTP request is made.
ApiError – If a by-filter delete carries a text-match operator, or the index is a dedicated index scaled to zero replicas.
- Return type:
None
Examples
By ID:
idx.delete(ids=["article-101", "article-102"], namespace="articles-en")
By metadata filter, which deletes every vector the filter admits:
idx.delete( filter={"status": {"$eq": "retracted"}}, namespace="articles-en", )
Emptying a whole namespace is unbounded and cannot be undone:
idx.delete(delete_all=True, namespace="articles-staging")
Note
Three things are true only of a by-filter delete. ids alongside filter is rejected here rather than sent, because the server lets the filter win and would delete everything it matches rather than the intersection —
query()with the filter first, then delete the IDs you got back. A text-match operator ($match_phrase,$match_all,$match_any) is rejected rather than ignored, because evaluated against metadata it matches everything and would widen the delete to every record the rest of the filter admits; text matching belongs insearch(). And a by-filter delete reads before it writes, so a dedicated index scaled to zero replicas refuses it — add replicas first. Deleting by ID or withdelete_allis subject to none of this.See also
delete_namespace()— removes the namespace along with everything in it, wheredelete_all=Trueempties it and leaves it in place.
- update(*, id=None, values=None, sparse_values=None, set_metadata=None, namespace='', filter=None, dry_run=False, timeout=None)[source]¶
Patch one vector by ID, or patch metadata across a filter.
A partial update: fields you do not mention keep the values they had, so
set_metadata={"year": 2021}leaves every other metadata key in place. Exactly one selector — id or filter — and a by-filter update is metadata-only, since values and sparse_values belong to one record. The write applies asynchronously, so a read straight afterwards can still see the old value.- Parameters:
id (str | None) – ID of the one vector to patch, e.g.
"article-101". Must be 1-512 ASCII characters without a NUL.values (list[float] | None) – Replacement dense values, at your index’s dimension. Only with id.
sparse_values (SparseValues | dict[str, Any] | None) – Replacement sparse vector, with
indicesandvalueskeys. Only with id.set_metadata (dict[str, Any] | None) – Metadata keys to set or overwrite, e.g.
{"year": 2021}. Keys you omit are left as they are; this never clears a field.namespace (str) – Namespace to target, e.g.
"movies-en". Defaults to the index’s default namespace.filter (dict[str, Any] | None) – Metadata filter expression selecting which vectors to patch, e.g.
{"genre": {"$eq": "drama"}}. Must carry at least one condition — see the note below.dry_run (bool) – Report how many records the filter would touch without writing anything. Ignored for a by-ID update. Run it first when the filter is broader than you can check by eye.
timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
UpdateResponsewhosematched_recordscounts the records patched, or underdry_runthe records that would have been. It isNonewhen the server does not report a count, which a by-ID update does not.- Raises:
PineconeValueError – If both or neither of id and filter are given, if filter is combined with values or sparse_values, or if filter is empty. Raised before any HTTP request is made.
ApiError – If a by-filter update carries a text-match operator, or the index is a dedicated index scaled to zero replicas.
- Return type:
Examples
Replacing one vector’s values, truncated here to three floats:
idx.update( id="article-101", values=[0.012, -0.087, 0.153], namespace="articles-en", )
Patching metadata across a filter.
dry_runreports the reach first, and thegenreof every patched record survives untouched:preview = idx.update( filter={"genre": {"$eq": "drama"}}, set_metadata={"reviewed": True}, namespace="movies-en", dry_run=True, ) print(preview.matched_records) idx.update( filter={"genre": {"$eq": "drama"}}, set_metadata={"reviewed": True}, namespace="movies-en", )
Note
Two things are true only of a by-filter update. A text-match operator (
$match_phrase,$match_all,$match_any) is rejected rather than ignored, because evaluated against metadata it matches everything and would widen the patch to every record the rest of the filter admits; text matching belongs insearch(). And a by-filter update reads before it writes, so a dedicated index scaled to zero replicas refuses it — add replicas first. Updating by ID is subject to neither.See also
upsert()— replaces a whole vector rather than patching it, and creates it if the ID is new.
- describe_index_stats(*, filter=None, timeout=None)[source]¶
Report vector counts, dimension, and fullness for this index.
The counts lag writes, so a vector just upserted may not be counted yet.
- Parameters:
filter (dict[str, Any] | None) – Metadata filter expression. Accepted for API compatibility, but a non-empty filter is rejected for every index type, so the call fails instead of returning filtered counts. Leave it unset: the statistics returned always describe the whole index.
timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
DescribeIndexStatsResponsewithtotal_vector_count,dimension,index_fullness, andnamespacesmapping each namespace name to a summary carrying itsvector_count. The default namespace appears in that mapping under the empty string.- Raises:
ApiError – If filter is non-empty. Every index type rejects it.
- Return type:
Examples
>>> idx = pc.index(name="article-search") >>> idx.describe_index_stats().total_vector_count 0
Per-namespace counts come back on the same response:
stats = idx.describe_index_stats() print(stats.dimension, stats.index_fullness) for name, summary in stats.namespaces.items(): print(name or "(default)", summary.vector_count)
See also
list_namespaces()— namespace record counts alongside each namespace’s schema andsize_bytes.
- search(*, namespace, top_k=None, inputs=None, vector=None, id=None, filter=None, fields=None, rerank=None, match_terms=None, query=None, timeout=None)[source]¶
Search records by text, vector, or ID, optionally reranking the hits.
Pass inputs and the index’s own embedding model turns your text into the query vector server-side — that is what separates this from
query(), where you supply the vector. A vector or an id works here too, for the cases where you already have one.- Parameters:
namespace (str) – Namespace to search, e.g.
"articles-en". Required and non-empty.top_k (int) – Number of results to return, at least 1, e.g.
10.inputs (SearchInputs | dict[str, Any] | None) – Inputs for server-side embedding (e.g.
{"text": "query text"}). UseSearchInputsfor typed key validation and IDE autocompletion (e.g.SearchInputs(text="query text")).vector (list[float] | dict[str, Any] | None) – Query vector. Pass a
list[float]for a dense-only query (wrapped automatically as{"values": [...]}) or a dict for sparse/hybrid queries with keysvalues,sparse_indices, and/orsparse_values(passed through as-is). SeeSearchQueryVectorfor the typed helper.id (str | None) – ID of an existing record to use as the query.
filter (dict[str, Any] | None) – Metadata filter expression.
fields (list[str] | None) – Field names to include in results. When
None, the server returns all available fields.rerank (RerankConfig | dict[str, Any] | None) – Reranking configuration with
model(required),rank_fields(required), and optionaltop_n,parameters,querykeys. UseRerankConfigfor IDE autocompletion.match_terms (dict[str, Any] | None) – Term-matching constraint for sparse search. Requires keys
"strategy"(currently only"all") and"terms"(list of strings). Valid only on a text query — combined withvectororidit is rejected — and only on a sparse index whose embedding model supports it; the server names the supported model when it refuses.Nonedisables term matching.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
query (SearchQuery | dict[str, Any] | None) – The pre-flattening form of this call —
top_kplus one ofinputs,vector, orid, nested in one mapping. Pass the fields directly instead.
- Returns:
SearchRecordsResponsewhoseresult.hitsare ordered from most to least relevant. Read eachHitashit.id,hit.score, andhit.fields; the hits nest one level down, underresult.usagebreaks the cost out by stage.- Raises:
PineconeValueError – If
namespaceis not a non-empty string,top_kis below 1, orrerankis missingmodelorrank_fields. Raised before any HTTP request is made.TypeError – If
queryis combined with any of the flat keyword arguments it replaces (top_k,inputs,vector,id,filter,match_terms) — pass one form or the other, not both — or ifqueryis neither aSearchQuerynor a mapping.
- Return type:
Examples
Text in, embedded server-side. The hits nest one level down, under
result— forgetting that is the usual first stumble here:>>> idx = pc.index(name="article-search") >>> response = idx.search( ... namespace="articles-en", ... top_k=2, ... inputs={"text": "benefits of vector databases for search"}, ... fields=["chunk_text"], ... ) >>> [(hit.id, hit.score) for hit in response.result.hits] [('article-1', 0.92), ('article-2', 0.74)] >>> response.result.hits[0].fields["chunk_text"] 'Vector databases accelerate AI search.'
Reranking in the same call retrieves
top_kand returns only thetop_nthe reranker likes best, so the hit count drops:>>> response = idx.search( ... namespace="articles-en", ... top_k=2, ... inputs={"text": "benefits of vector databases"}, ... rerank={ ... "model": "bge-reranker-v2-m3", ... "rank_fields": ["chunk_text"], ... "top_n": 1, ... }, ... ) >>> len(response.result.hits) 1 >>> response.usage.rerank_units 1
See also
query()— for a vector-based index, where you supply the query vector and nothing is embedded for you.documents—documents.searchfor a schema-based index, which stores JSON records and ranks withscore_byclauses.pc.inference.rerank— reranking on its own, for hits that came from somewhere other than this index.
- search_records(*, namespace, top_k=None, inputs=None, vector=None, id=None, filter=None, fields=None, rerank=None, match_terms=None, query=None, timeout=None)[source]¶
Alias for
search(), kept for callers written against 9.x.Every argument, return value and error is
search()’s. Call that one in new code; nothing here differs.
- create_namespace(*, name, schema=None)[source]¶
Create a named namespace in the index.
- Parameters:
name (str) – Name for the new namespace, e.g.
"movies-en". Must be ASCII, must not contain the NUL character, and must be 1-512 characters long.__default__is reserved and cannot be created: it names the namespace requests address when they omit a namespace, so it always exists.schema (dict[str, Any] | None) – Optional metadata-index configuration,
{"fields": {<field>: {"filterable": True}}}. Omitting it does not mean “index everything”: the namespace inherits the index’s own metadata-index configuration, so an index that restricts which fields are indexed passes that restriction on. Supply schema to override the inherited configuration for this namespace, indexing exactly the fields listed.filterableis required on each field and must beTrue— to leave a field unindexed, omit it fromfields.
- Returns:
NamespaceDescriptionwith the namespace name, record count, schema, indexed fields, andsize_bytes.- Raises:
PineconeValueError – If name violates the rules above, or schema is malformed. Raised before any HTTP request is made.
ConflictError – a namespace of that name already exists.
- Return type:
Examples
ns = idx.create_namespace(name="movies-en") print(ns.name, ns.record_count, ns.size_bytes)
Naming the filterable fields up front overrides what the namespace would otherwise inherit from the index:
ns = idx.create_namespace( name="movies-fr", schema={"fields": {"genre": {"filterable": True}}}, ) print(ns.indexed_fields)
See also
describe_namespace()— the same description for a namespace that already exists.list_namespaces()— the namespaces the index already has.
- describe_namespace(*, name=None, **kwargs)[source]¶
Describe a namespace by name.
This operation is rate limited per index, independently of the other namespace operations. Prefer
list_namespaces()when describing more than one namespace: it returns the same information for every namespace in a single request and is not subject to that limit.- Parameters:
- Returns:
NamespaceDescriptionwith the namespace name, record count, schema, indexed fields, andsize_bytes.size_bytesis approximate: data written before size tracking reads as 0, and recently deleted data may still be counted; compaction converges the value.- Raises:
PineconeValueError – If name violates the rules above. Raised before any HTTP request is made.
TypeError – If unexpected keyword arguments are passed.
NotFoundError – no namespace of that name exists on the index.
RateLimitError – this operation’s per-index limit was exceeded. Use
list_namespaces()to describe many namespaces.
- Return type:
Examples
ns = idx.describe_namespace(name="movies-en") print(ns.name, ns.record_count, ns.size_bytes)
The namespace that unnamespaced requests address answers to
__default__:ns = idx.describe_namespace(name="__default__") print(ns.record_count)
See also
list_namespaces()— every namespace at once, and the operation to reach for when you are describing more than one.
- delete_namespace(*, name=None, timeout=None, **kwargs)[source]¶
Delete a namespace and everything in it.
Irreversible: every vector in the namespace goes with it, and the namespace itself stops existing. To empty a namespace but keep it, use
delete()withdelete_all=True.- Parameters:
- Returns:
None — a successful delete returns no payload.
- Raises:
PineconeValueError – If name violates the rules above. Raised before any HTTP request is made.
TypeError – If unexpected keyword arguments are passed.
NotFoundError – no namespace of that name exists on the index.
- Return type:
None
Examples
idx.delete_namespace(name="movies-deprecated")
See also
delete()—delete_all=Trueempties a namespace and leaves it in place.
- list_namespaces_paginated(*, prefix=None, limit=None, pagination_token=None)[source]¶
Fetch one page of namespace descriptions, holding the token yourself.
list_namespaces()walks the pages for you; reach for this one when you need to persist the token between calls or hand it to a caller of your own. See Pagination.- Parameters:
prefix (str | None) – Return only namespaces whose names start with this prefix, e.g.
"movies-". Must be ASCII, must not contain the NUL character, and must be at most 512 characters. The empty prefix matches every namespace.limit (int | None) – Maximum number of namespaces in this page, 1-100.
pagination_token (str | None) –
pagination.nextfrom the previous response.None(default) fetches the first page.
- Returns:
ListNamespacesResponsewithnamespaces, each aNamespaceDescriptioncarrying its record count, schema, indexed fields andsize_bytes, plus a total count andpaginationwhosenextisNoneon the last page.- Raises:
PineconeValueError – If prefix or limit violates the rules above. Raised before any HTTP request is made.
- Return type:
Examples
response = idx.list_namespaces_paginated(prefix="movies-", limit=10) for ns in response.namespaces: print(ns.name, ns.record_count, ns.size_bytes) next_token = response.pagination.next if response.pagination else None
See also
list_namespaces()— the same listing with the token handled for you.Pagination — how the SDK pages generally.
- list_namespaces(*, prefix=None, limit=None)[source]¶
List every namespace, a page at a time.
Yields one
ListNamespacesResponseper page and follows the pagination tokens itself, so nothing is requested until you iterate. A page describes every namespace it holds in one request, which makes this the operation to reach for over repeateddescribe_namespace()calls — those are rate limited per index and this is not.- Parameters:
- Yields:
ListNamespacesResponseper page, each carryingnamespacesofNamespaceDescriptionwith record count, schema, indexed fields andsize_bytes. A page with no namespaces is skipped rather than yielded.- Raises:
PineconeValueError – If prefix or limit violates the rules above. Raised on first iteration, not at the call.
- Return type:
Examples
for page in idx.list_namespaces(prefix="movies-"): for ns in page.namespaces: print(ns.name, ns.record_count, ns.size_bytes)
See also
list_namespaces_paginated()— one page, with the token in your hands.describe_namespace()— one namespace, when you know its name.Pagination — how the SDK pages generally.
- list_paginated(*, prefix=None, limit=None, pagination_token=None, namespace='', timeout=None)[source]¶
Fetch one page of vector IDs, holding the token yourself.
IDs only — no values and no metadata.
list()walks the pages for you; reach for this one when you need to persist the token between calls. See Pagination.- Parameters:
prefix (str | None) – Return only IDs starting with this prefix, e.g.
"article-2024#". At most 512 ASCII characters without a NUL; the empty prefix matches everything.limit (int | None) – Maximum number of IDs in this page, 1-100.
pagination_token (str | None) –
pagination.nextfrom the previous response.None(default) fetches the first page.namespace (str) – Namespace to list from, e.g.
"articles-en". Defaults to the index’s default namespace.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
ListResponsewithvectors— each carrying anidand nothing else — plusnamespace,usage, andpaginationwhosenextis the token for the following page orNoneon the last one.- Raises:
PineconeValueError – If prefix is not legal or limit falls outside 1-100. Raised before any HTTP request is made.
- Return type:
Examples
response = idx.list_paginated( prefix="article-2024#", limit=50, namespace="articles-en", ) for item in response.vectors: print(item.id) next_token = response.pagination.next if response.pagination else None
See also
list()— the same listing with the token handled for you.fetch()— the vectors behind those IDs.Pagination — how the SDK pages generally.
- list(*, prefix=None, limit=None, namespace='', timeout=None)[source]¶
List vector IDs in a namespace, a page at a time.
IDs only — no values and no metadata. Yields one
ListResponseper page and follows the pagination tokens itself, so nothing is requested until you iterate, and a bad prefix or limit is not reported until then either.- Parameters:
prefix (str | None) – Return only IDs starting with this prefix, e.g.
"article-2024#". At most 512 ASCII characters without a NUL; the empty prefix matches everything.limit (int | None) – Maximum number of IDs per page, 1-100.
namespace (str) – Namespace to list from, e.g.
"articles-en". Defaults to the index’s default namespace.timeout (float | None) – Per-request timeout in seconds, applied to each underlying page request. Overrides the client-level default for this call only.
- Yields:
ListResponseper page, each carryingvectorsof IDs. A page with no IDs is skipped rather than yielded.- Raises:
PineconeValueError – If prefix is not legal or limit falls outside 1-100. Raised on first iteration, not at the call.
- Return type:
Examples
for page in idx.list(prefix="article-2024#", namespace="articles-en"): ids = [item.id for item in page.vectors] fetched = idx.fetch(ids=ids, namespace="articles-en") for vid, vec in fetched.vectors.items(): print(vid, vec.metadata)
See also
list_paginated()— one page, with the token in your hands.fetch()— the vectors behind a page of IDs.Pagination — how the SDK pages generally.
- start_import(uri, *, error_mode=None, integration_id=None)[source]¶
Start a server-side bulk import of vectors from cloud storage.
Returns as soon as the import is accepted, not when it finishes: the work happens server-side, and
describe_import()is how you learn whether it completed. Nothing here polls for you.- Parameters:
uri (str) – Directory prefix holding the Parquet files, not a single file. Three forms are accepted:
s3://for Amazon S3,gs://for Google Cloud Storage, and anhttps://URL naming an Azure Blob Storage container.s3://additionally requires that the index itself be hosted on AWS.error_mode (str | None) – How to handle a record the import cannot read.
"continue"skips it and imports the rest;"abort"ends the whole import at the first such record. Case-insensitive. Defaults to"abort"when omitted, so an unreadable record fails the import unless you opt into skipping.integration_id (str | None) – Optional integration ID for the import.
- Returns:
StartImportResponsewithid, the handle every other import method takes.- Raises:
PineconeValueError – If error_mode is supplied but is neither
"continue"nor"abort". Raised before any HTTP request is made.ApiError – If uri is empty or longer than the server accepts, uses an unsupported scheme, is an
s3://URI on an index not hosted on AWS, or names an S3 directory bucket, which imports do not support.
- Return type:
Examples
The call returns the moment the import is accepted:
>>> idx = pc.index(name="article-search") >>> response = idx.start_import(uri="s3://acme-exports/articles/")
Waiting it out is on you; three of the five statuses are terminal:
import time import_op = idx.describe_import(response.id) while import_op.status not in ("Completed", "Failed", "Cancelled"): time.sleep(10) import_op = idx.describe_import(response.id) print(import_op.status, import_op.records_imported)
error_mode="continue"finishes the import around records it cannot read, rather than stopping at the first one:>>> response = idx.start_import( ... uri="s3://acme-exports/articles/", ... error_mode="continue", ... )
Note
uri must name a directory of Parquet files following Pinecone’s import schema. See the import guide for that schema and the supported storage formats.
See also
describe_import()— progress, and the terminal status.cancel_import()— stopping one that is still running.upsert()— the right tool below the millions of vectors an import is for.
- describe_import(id)[source]¶
Describe a bulk import operation by ID.
- Parameters:
id (str | int) – The
idstart_import()returned, e.g."import-123". Anintis accepted and stringified. 1-1000 characters.- Returns:
ImportModelwithstatus— one of"Pending","InProgress","Failed","Completed","Cancelled", the last three terminal — pluspercent_complete,records_imported,uri, anderrorwhen it failed.- Raises:
PineconeValueError – If id is empty or over 1000 characters. Raised before any HTTP request is made.
- Return type:
Examples
>>> idx = pc.index("article-search") >>> import_op = idx.describe_import("import-123") >>> print(import_op.status, import_op.percent_complete, import_op.records_imported) InProgress 50.0 12000 >>> import_op.uri 's3://acme-exports/articles/'
Read
erroronly oncestatusis"Failed"; it isNoneotherwise.if import_op.status == "Failed": print(import_op.error)
See also
start_import()— starting one, and theidthese methods take.list_imports()— every import on the index rather than one.
- cancel_import(id)[source]¶
Cancel a bulk import operation by ID.
- Parameters:
id (str | int) – The
idstart_import()returned, e.g."import-123". Anintis accepted and stringified. 1-1000 characters.- Returns:
None — a successful cancellation returns no payload. Poll
describe_import()to see the operation reach"Cancelled".- Raises:
PineconeValueError – If id is empty or over 1000 characters. Raised before any HTTP request is made.
- Return type:
None
Examples
>>> idx = pc.index(name="article-search") >>> idx.cancel_import("import-123")
See also
start_import()— starting one, and theidthese methods take.list_imports()— every import on the index rather than one.
- list_imports(*, limit=None, pagination_token=None)[source]¶
List every bulk import on this index, following pagination.
Yields the
ImportModelobjects themselves rather than pages, and fetches the next page as you exhaust the current one, so nothing is requested until you iterate. See Pagination.- Parameters:
- Yields:
ImportModelper import operation, oldest page first.- Raises:
ApiError – If a page request fails part-way through the listing; the imports already yielded are still yours, the rest are not.
- Return type:
Examples
>>> idx = pc.index(name="article-search") >>> for imp in idx.list_imports(): ... print(imp.id, imp.status, imp.uri)
See also
list_imports_paginated()— one page, with the token in your hands.describe_import()— one import, when you know itsid.Pagination — how the SDK pages generally.
- list_imports_paginated(*, limit=None, pagination_token=None)[source]¶
Fetch one page of bulk imports, holding the token yourself.
list_imports()walks the pages for you; reach for this one when you need to persist the token between calls. See Pagination.- Parameters:
- Returns:
ImportListyou can iterate for this page’sImportModelobjects, withpagination.nextholding the token for the following page orNoneon the last one.- Return type:
Examples
>>> idx = pc.index(name="article-search") >>> page = idx.list_imports_paginated(limit=10) >>> [imp.id for imp in page] []
paginationis absent on the last page, which is how you know to stop:>>> page.pagination is None True
See also
list_imports()— the same listing with the token handled for you.Pagination — how the SDK pages generally.
- close()[source]¶
Close the underlying HTTP client and release its resources.
Calls on a closed index fail. Prefer
withover calling this by hand, which closes the client even if the body raises.- Returns:
None.
- Return type:
None
Examples
with pc.index(name="article-search") as idx: idx.upsert( vectors=[("article-101", [0.012, -0.087, 0.153])], namespace="articles-en", )
Documents¶
- class pinecone.client.documents.Documents(*, http, host)[source]¶
Bases:
objectDocument data-plane operations for a schema-based index.
A schema-based index stores JSON documents instead of raw vectors. Every document carries the reserved
_idkey; every other key is a field of your own, either declared in the index schema or free-form metadata. Accessed viadocuments. Not constructed directly — the parentIndexbuilds and caches its own instance on first access.On a vector-based index, use the vector methods on
Indexitself (upsert(),query()) rather than this namespace. Every method here is keyword-only. A positional argument raisesPineconeValueErrorlisting the accepted keywords, and a misspelled keyword raisesTypeErrorsuggesting the one you meant.Examples
from pinecone import Pinecone pc = Pinecone(api_key="your-api-key") with pc.index(name="articles-en") as idx: idx.documents.upsert( namespace="published", documents=[{"_id": "article-101", "title": "Intro to vectors"}], )
See also
Error Handling — the exceptions any of these methods can raise, and which ones are worth retrying.
- Parameters:
http (HTTPClient)
host (str)
- upsert(*, namespace, documents, timeout=None)[source]¶
Upsert documents into a namespace.
Each document must include an
_idfield (a unique, non-empty ASCII string of at most 512 characters) along with fields defined in the index schema or arbitrary metadata fields. If a document with the same_idalready exists in the namespace, it is overwritten.Pinecone applies the upsert asynchronously, so documents may not be immediately visible to
search()orfetch().- Parameters:
namespace (str) – Target namespace (required, non-empty).
documents (Sequence[Mapping[str, Any] | DocumentRecord]) – The documents to upsert (1-1000 per request). Each element is a dict with an
_idkey or aDocumentRecord. For larger lists, usebatch_upsert().timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
UpsertDocumentsResponsewith the count of documents accepted for upsert.- Raises:
PineconeValueError – If
namespaceis empty,documentsis empty or over 1000 entries, or any document has a missing, empty, non-string, non-ASCII, over-512-character, or duplicate_id— the message names the offending document’s position.ApiError – If one request exceeds the server’s cap on encoded request size — a document count inside the accepted range can still be too large. Send fewer documents per request, or use
batch_upsert().
- Return type:
Examples
_idis the only reserved key;titlehere is a field of your own, and every document may carry a different set of them:>>> from pinecone import Pinecone >>> pc = Pinecone(api_key="your-api-key") >>> idx = pc.index(name="articles-en") >>> response = idx.documents.upsert( ... namespace="published", ... documents=[ ... {"_id": "article-101", "title": "Intro to vectors"}, ... {"_id": "article-102", "title": "Advanced retrieval"}, ... ], ... ) >>> response.upserted_count 2
See also
batch_upsert()— for upserting large document lists in parallel batches.upsert()— for indexes where you provide your own vectors.
- batch_upsert(*, namespace, documents, batch_size=50, max_concurrency=None, show_progress=True, timeout=None, total_timeout=None)[source]¶
Upsert a large list of documents in parallel batches.
Splits documents into chunks of batch_size and submits them through the host’s admission gate. Concurrency is bounded by max_concurrency and by the host’s adaptive concurrency limit, whichever is lower, so a struggling backend applies backpressure instead of being handed every batch at once. Per-batch HTTP failures are captured in the returned
BatchResultrather than raised, so one failed batch does not abort the rest; retry only the failures by passingresult.failed_itemsback in.- Parameters:
namespace (str) – Target namespace (required, non-empty).
documents (Sequence[Mapping[str, Any] | DocumentRecord]) – Documents to upsert. Each element is a dict with an
_idkey or aDocumentRecord; IDs must be unique across the whole list.batch_size (int) – Maximum documents per request (1-1000, default 50).
max_concurrency (int | None) – Upper bound on concurrent requests (1-64). Defaults to
None, which lets the admission gate useDEFAULT_MAX_CONCURRENCY(8); the gate’s own adaptive limit for the host applies on top of whatever is passed.show_progress (bool) – Display a progress bar when
tqdmis installed. Defaults toTrue.timeout (float | None) – Per-request timeout in seconds applied to each batch’s request — not to the whole call.
total_timeout (float | None) – Deadline in seconds for the whole batched upsert, as opposed to timeout, which bounds a single attempt of a single batch. On expiry no further batches are submitted, and the un-submitted ones are reported in
result.failed_itemsso they can be retried.None(default) means no deadline. See the note below for whatresult.timed_outdoes and does not tell you.
- Returns:
BatchResultwith aggregated success and failure counts; per-batch errors are inresult.errorsand the affected documents inresult.failed_items.- Raises:
PineconeValueError – If
namespaceis empty,documentsis empty or contains an invalid or duplicate_id,batch_sizeis outside [1, 1000], ormax_concurrencyis outside [1, 64].- Return type:
Examples
documents = [ {"_id": f"article-{i}", "title": f"Article {i}"} for i in range(5000) ] result = idx.documents.batch_upsert( namespace="published", documents=documents, batch_size=100, max_concurrency=8, total_timeout=60.0, ) print(result.successful_item_count, result.failed_item_count) if result.timed_out: result = idx.documents.batch_upsert( namespace="published", documents=result.failed_items, batch_size=100, )
Note
Batches already in flight when total_timeout expires are awaited and never cancelled, because dropping one client-side would not stop the host from applying it. So
result.timed_outisTrueonly when something was actually left unsent — if the in-flight batches were the last ones and all landed, the upsert succeeded late rather than failing. Time spent waiting for the host’s admission gate counts against the budget, so a throttled host can consume it without a request being sent.See also
upsert()— for a single-request upsert of up to 1000 documents.How Bulk Ingest Behaves — choosing a batch size and concurrency, and reading the gate counters on the result.
- search(*, namespace, score_by, top_k, include_fields=None, filter=None, timeout=None)[source]¶
Search documents in a namespace using one or more scoring methods.
Returns the
top_kmost similar documents ranked by the given scoring methods (dense vector, sparse vector, BM25 text, or Lucene query string similarity).- Parameters:
namespace (str) – Namespace to search (required, non-empty).
score_by (Sequence[TextQuery | QueryStringQuery | DenseVectorQuery | SparseVectorQuery | Mapping[str, Any]]) – Scoring methods to rank documents by (1-100 clauses). Items are typed variants (
TextQuery,QueryStringQuery,DenseVectorQuery,SparseVectorQuery) or plain dicts with atypekey.textandquery_stringclauses may be combined; adense_vectororsparse_vectorclause must appear alone.top_k (int) – Number of top-ranked documents to return (1-10000).
include_fields (Sequence[str] | None) – Document fields to include in each match. Omitting it (the default) or passing
[]returns only_idand_score;["*"]returns every field, even alongside other names.fetch()is the opposite — there, omitting the argument returns every field.filter (Mapping[str, Any] | None) – Metadata filter expression restricting the documents searched, or
None.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
SearchDocumentsResponsewithmatches(ordered from most to least similar),namespace, andusage. Each match is aDocument, reached asdoc.id,doc.score, anddoc.<field>for the fieldsinclude_fieldsasked for.- Raises:
PineconeValueError – If
namespaceis empty,score_byis empty, over 100 clauses, or combines a vector clause with any other clause, ortop_kis outside [1, 10000].- Return type:
Examples
>>> from pinecone import Pinecone, TextQuery >>> pc = Pinecone(api_key="your-api-key") >>> idx = pc.index(name="articles-en") >>> response = idx.documents.search( ... namespace="published", ... top_k=5, ... score_by=[TextQuery(query="machine learning", fields=["content"])], ... include_fields=["title", "content"], ... filter={"category": {"$eq": "tech"}}, ... ) >>> for doc in response.matches: ... print(doc.id, doc.score) article-101 0.92 article-102 0.74
- fetch(*, namespace, ids=None, filter=None, include_fields=None, pagination_token=None, timeout=None)[source]¶
Fetch documents from a namespace by ID or by metadata filter.
Exactly one of
idsorfiltermust be provided. A filtered fetch returns matching documents a page at a time, withresponse.paginationcarrying the token for the next page; the server fixes the page size, so there is no page-size argument here.- Parameters:
namespace (str) – Namespace to fetch from (required, non-empty).
ids (Sequence[str] | None) – Document IDs to fetch (1-1000). IDs that do not exist are omitted from the result rather than raising. Mutually exclusive with
filter.filter (Mapping[str, Any] | None) – Non-empty metadata filter expression selecting the documents to fetch. Mutually exclusive with
ids.include_fields (Sequence[str] | None) – Document fields to include in each document. Omitting it (the default),
[], or["*"]each return every field; a list of names returns just those.search()is the opposite — there, omitting the argument returns only_idand_score.pagination_token (str | None) – Token from a previous filtered fetch response to retrieve the next page. Only valid together with
filter.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
FetchDocumentsResponsewithdocuments(document ID mapped to aDocument, reached asdoc.<field>),namespace,usage, and — for filtered fetches with more results —pagination.- Raises:
PineconeValueError – If
namespaceis empty, both or neither ofidsandfilterare provided,filteris an empty dict,idsexceeds 1000 entries, orpagination_tokenis passed withoutfilter.- Return type:
Examples
Fetch specific documents by ID. IDs that do not exist are absent from
response.documentsrather than raising:>>> from pinecone import Pinecone >>> pc = Pinecone(api_key="your-api-key") >>> idx = pc.index(name="articles-en") >>> response = idx.documents.fetch( ... namespace="published", ... ids=["article-101", "article-102"], ... ) >>> for doc_id, doc in response.documents.items(): ... print(doc_id, doc.title) article-101 Intro to vectors article-102 Advanced retrieval
Fetch by filter instead. A filtered fetch is paginated, so read each page’s documents before asking for the next one — the loop below is the whole retrieval, not just the token bookkeeping:
>>> pagination_token = None >>> while True: ... response = idx.documents.fetch( ... namespace="published", ... filter={"category": {"$eq": "tech"}}, ... pagination_token=pagination_token, ... ) ... for doc_id, doc in response.documents.items(): ... print(doc_id, doc.title) ... if response.pagination is None: ... break ... pagination_token = response.pagination.next article-101 Intro to vectors article-102 Advanced retrieval
See also
search()— when you want the best-matching documents rather than every document that satisfies a filter.fetch()— for indexes where you provide your own vectors.Pagination — the pagination shapes the SDK uses and when each applies.
- delete(*, namespace, ids=None, filter=None, delete_all=False, timeout=None)[source]¶
Delete documents from a namespace by ID, filter, or delete-all flag.
Exactly one of
ids,filter, ordelete_allmust be provided. Deleting IDs that do not exist does not raise an error.Pinecone applies the delete asynchronously. For a filtered delete,
response.matched_recordsis the point-in-time count of matching documents when the delete was accepted, not a guarantee of the number ultimately deleted.- Parameters:
namespace (str) – Namespace to delete from (required, non-empty).
ids (Sequence[str] | None) – Document IDs to delete (1-1000). Mutually exclusive with
filteranddelete_all.filter (Mapping[str, Any] | None) – Non-empty metadata filter expression selecting the documents to delete. Text-match operators (
$match_phrase,$match_all,$match_any) are not supported here. Mutually exclusive withidsanddelete_all. Not available on an index with dedicated read capacity scaled to 0 replicas — scale up replicas first.delete_all (bool) – If
True, delete all documents in the namespace. Mutually exclusive withidsandfilter.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
DeleteDocumentsResponse—matched_recordsis populated only for filtered deletes (Nonefor by-ID and delete-all paths, and when the count could not be read in time).- Raises:
PineconeValueError – If
namespaceis empty, zero or more than one ofids/filter/delete_allis provided,filteris an empty dict, oridsexceeds 1000 entries.- Return type:
Examples
Delete specific documents by ID:
idx.documents.delete(namespace="published", ids=["article-101"])
Delete every document matching a filter:
>>> from pinecone import Pinecone >>> pc = Pinecone(api_key="your-api-key") >>> idx = pc.index(name="articles-en") >>> response = idx.documents.delete( ... namespace="published", ... filter={"category": {"$eq": "obsolete"}}, ... ) >>> response.matched_records 2
Or empty a namespace outright.
delete_allremoves every document in the namespace named — it takes noidsorfilterto narrow it:idx.documents.delete(namespace="drafts", delete_all=True)
See also
delete_namespace()— to remove the namespace itself, rather than emptying it withdelete_all.delete()— for indexes where you provide your own vectors.
- update(*, namespace, documents=None, filter=None, set_fields=None, remove_fields=None, timeout=None)[source]¶
Apply partial updates to documents in a namespace.
Documents are selected either per ID with
documents, or in bulk withfilterplusset_fieldsand/orremove_fields. The two shapes are mutually exclusive. Fields that are not mentioned are left unchanged, and an update naming a document that does not exist is accepted as a no-op rather than raising.Pinecone applies the update asynchronously — for a filtered update,
response.matched_recordsis the point-in-time count of matching documents when the update was accepted, not a guarantee of the number ultimately patched.- Parameters:
namespace (str) – Namespace to update in (required, non-empty).
documents (Sequence[Mapping[str, Any] | UpdateDocumentRecord] | None) – Per-document patches (1-1000). Each element is a dict with an
_idkey or anUpdateDocumentRecord. Any key other than_idand_remove_fieldssets a new value for that field; the names in_remove_fieldsare removed from the document._idvalues must be unique within the request. Mutually exclusive withfilter,set_fields, andremove_fields.filter (Mapping[str, Any] | None) – Non-empty metadata filter expression selecting the documents to patch. Text-match operators (
$match_phrase,$match_all,$match_any) are not supported here. Mutually exclusive withdocuments. Not available on an index with dedicated read capacity scaled to 0 replicas — scale up replicas first.set_fields (Mapping[str, Any] | None) – Fields to set on every document matching
filter, and the values to set them to. Only valid withfilter.remove_fields (Sequence[str] | None) – Names of the fields to remove from every document matching
filter. Only valid withfilter.timeout (float | None) – Per-request timeout in seconds. Overrides the client-level default for this call only.
- Returns:
UpdateDocumentsResponse—matched_recordsis populated only for filtered updates (Nonefor per-ID updates, and when the count could not be read in time).- Raises:
PineconeValueError – If
namespaceis empty,documentsis combined with any by-filter field, neitherdocumentsnorfilteris given,set_fieldsorremove_fieldsis passed withoutfilter,filteris an empty dict or carries no patch,documentsis empty or exceeds 1000 entries, or a patch is malformed — the message names the offending position.ApiError – If a field value is
None, which the server rejects — use_remove_fields(per-ID) orremove_fields(by-filter) to remove a field instead.
- Return type:
Examples
Patch documents by ID. Each key other than the reserved
_idand_remove_fieldssets that field’s value; fields the patch does not name keep the values they already have, soarticle-101here gets a newtitleand is otherwise untouched:idx.documents.update( namespace="published", documents=[ {"_id": "article-101", "title": "An introduction to vector search"}, {"_id": "article-102", "_remove_fields": ["draft_notes"]}, ], )
article-102keeps every field it has exceptdraft_notes:_remove_fieldsnames fields to delete rather than setting a field called_remove_fields.Patch every document matching a filter instead, setting one field and removing another across all of them:
response = idx.documents.update( namespace="published", filter={"category": {"$eq": "news"}}, set_fields={"review_status": "archived"}, remove_fields=["draft_notes"], ) print(response.matched_records)
- list(*, namespace, prefix=None, limit=None, pagination_token=None, timeout=None)[source]¶
List the documents in a namespace, following pagination lazily.
Returns a
Paginatorthat fetches pages on demand and stops when the server returns nopaginationtoken. Documents come back in sorted order by ID, carrying only their_id.- Parameters:
namespace (str) – Namespace to list from (required, non-empty).
prefix (str | None) – Return only documents whose IDs begin with this prefix. At most 512 characters, ASCII only (
\x01-\x7F).Nonelists every document.limit (int | None) – Maximum number of documents the server returns per page, 1-100. This tunes the page size, not the total — the paginator follows every page.
None(default) lets the server choose the page size. To stop early, break out of the loop.pagination_token (str | None) – Token from a previous list response to resume from, rather than starting at the first page.
timeout (float | None) – Per-request timeout in seconds, applied to each page request. Overrides the client-level default.
- Returns:
PaginatoroverListedDocumentRecordobjects. Supportsforloops,to_list(), andpages().- Raises:
PineconeValueError – If
namespaceis empty,prefixviolates the rules above, orlimitfalls outside 1-100. Raised by this call, before the paginator is returned.- Return type:
Examples
Iterate every document ID in the namespace, letting the paginator cross page boundaries for you:
>>> from pinecone import Pinecone >>> pc = Pinecone(api_key="your-api-key") >>> idx = pc.index(name="articles-en") >>> for doc in idx.documents.list(namespace="published", prefix="article-1"): ... print(doc.id) article-101 article-102
Or take the pages themselves, when you want to checkpoint a long walk on the token each page carries:
>>> for page in idx.documents.list(namespace="published", limit=20).pages(): ... print(len(page.items), page.pagination_token) 2 None
See also
fetch()— to read the fields of the documents, not just their IDs.list()— for indexes where you provide your own vectors.Pagination — the pagination shapes the SDK uses and when each applies.