Pinecone

Pinecone is the synchronous control-plane client: it creates and manages indexes, collections, backups, and assistants, and runs inference. Each resource type is a namespace property (pc.indexes, pc.collections, …) documented in its own section below. For reading and writing data, index() returns an Index.

class pinecone.Pinecone(api_key=None, *, host=None, additional_headers=None, source_tag=None, proxy_url=None, proxy_headers=None, ssl_ca_certs=None, ssl_verify=True, grpc_scheme=None, timeout=30.0, connection_pool_maxsize=0, retry_config=None, **kwargs)[source]

Bases: object

Entry point to Pinecone’s control plane, over blocking HTTP.

One client carries your API key, resolved host, and connection pool, so construct it once and reuse it. Its namespace properties — indexes, collections, backups, backup_schedules, restore_jobs, inference, and assistants — create and inspect those resources. Vectors are read and written on the data plane instead, through the separate client index() hands back.

AsyncPinecone covers the same surface for asyncio code, and Sync vs async clients compares the two; the one shape difference is index(), which is a plain call here and a coroutine there. Any call can raise the connection, timeout, and API errors catalogued in Error handling, and every Raises: section below names only what is specific to that method. Retries and resilience covers what the client retries on your behalf and what retry_config changes.

Parameters:
  • api_key (str | None) – Your Pinecone API key. None (default) reads PINECONE_API_KEY from the environment, which is how most deployments supply it.

  • host (str | None) – Control-plane host, e.g. "https://api.pinecone.io". A value with no scheme is read as https. None (default) reads PINECONE_CONTROLLER_HOST, then falls back to the public API. Point it elsewhere for a gateway, a private endpoint, or a local simulator.

  • additional_headers (Mapping[str, str] | None) – Headers added to every control-plane request, e.g. {"X-Request-Source": "nightly-reindex"}. A name matches the SDK’s own headers (X-Pinecone-Api-Version, User-Agent, Api-Key) regardless of case, and your value replaces the SDK’s, so exactly one is sent. When omitted, the client reads PINECONE_ADDITIONAL_HEADERS as a JSON object instead.

  • source_tag (str | None) – Attribution tag appended to the User-Agent, e.g. "acme-search-service". Lowercased, spaces become underscores, and anything outside a-z, 0-9, _ and : is dropped.

  • proxy_url (str | None) – Proxy for outgoing requests, e.g. "http://proxy.corp.internal:3128".

  • proxy_headers (Mapping[str, str] | None) – Headers sent to the proxy itself, for a proxy that authenticates.

  • ssl_ca_certs (str | None) – Path to a CA bundle file, or to a directory of them, for a corporate root or a self-signed endpoint. It wins over ssl_verify=False: pass both and verification stays on.

  • ssl_verify (bool) – Whether to verify the server’s certificate. True (default) is right everywhere but a throwaway test endpoint.

  • grpc_scheme (str | None) – URL scheme, "http" or "https", that index() with grpc=True dials the data plane over. State it when the data plane is reached over something other than public TLS (a plaintext gateway, an egress proxy, a private endpoint, or a local simulator) rather than leaving the SDK to assume one. None (default) falls back to the PINECONE_GRPC_SCHEME env var, and then to https. Has no effect on REST clients, which take the scheme from the host they are given.

  • timeout (float) – Deadline in seconds for a single HTTP attempt, not for the whole call — each retry gets its own. Must be greater than zero. Defaults to 30.0.

  • connection_pool_maxsize (int) – Ceiling on connections held open to the control plane. 0 (default) leaves httpx’s own ceiling in place; raise it for a process issuing many concurrent control-plane calls.

  • retry_config (RetryConfig | None) – Retry policy for control-plane requests, and for gRPC data-plane clients when you set it explicitly. None (default) uses the built-in policy, which suits most callers; see Retries and resilience for the defaults, for how to switch retries off, and for why it does not reach data-plane REST.

  • pool_threads (int | None) – Opt-in for the legacy async_req=True execution model on data-plane methods. When set, indexes created via index() accept async_req=True on upsert, query, describe_index_stats, and list_paginated. For new code, prefer AsyncPinecone or concurrent.futures.ThreadPoolExecutor. This keyword is here for 9.x callers.

  • kwargs (Any)

Raises:
  • PineconeValueError – If no API key is given and PINECONE_API_KEY is unset, since nothing would authenticate the first request. Also raised when the key is not a valid HTTP header value, such as a blank key or one with a trailing newline, so the failure is local and never echoes the key.

  • PineconeValueError – If proxy_url has a scheme other than http, https, socks5 or socks5h, no host, an invalid port, surrounding whitespace, or an unencoded #, / or ? in the username or password; the message masks the username and password.

  • PineconeTypeError – If a keyword argument other than those listed above is passed, which is how a misspelled parameter name surfaces. It derives from TypeError, so except TypeError catches it too.

  • FileNotFoundError – If ssl_ca_certs names 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 raises ssl.SSLError instead.

Examples

Construct once, then reach the control plane through the namespace properties. Leaving api_key off entirely reads it from PINECONE_API_KEY:

from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")
if not pc.indexes.exists("product-search"):
    pc.indexes.create(
        name="product-search",
        schema={"fields": {"your_vector": {
            "type": "dense_vector", "dimension": 1536, "metric": "cosine"}}},
    )

index() hands back a separate data-plane client scoped to one index, which is what reads and writes vectors. A query vector has to be as wide as the index’s dense field — the three floats below stand in for a full 1536-dimensional embedding:

idx = pc.index(name="product-search")
results = idx.query(vector=[0.012, -0.087, 0.153], top_k=10)
for match in results.matches:
    print(match.id, match.score)
__init__(api_key=None, *, host=None, additional_headers=None, source_tag=None, proxy_url=None, proxy_headers=None, ssl_ca_certs=None, ssl_verify=True, grpc_scheme=None, timeout=30.0, connection_pool_maxsize=0, retry_config=None, **kwargs)[source]
Parameters:
Return type:

None

property indexes: Indexes

Create, inspect, configure, and delete the project’s indexes.

Returns:

The Indexes namespace.

Examples

>>> for index in pc.indexes.list():
...     print(index.name, index.status.state)
property collections: Collections

Create and inspect collections, the static snapshots of a pod-based index.

A collection is the pod-based snapshot format. The serverless equivalent is a backup, under backups.

Returns:

The Collections namespace.

Examples

>>> for col in pc.collections.list():
...     print(col.name, col.status)
movie-embeddings-snapshot Ready
product-catalog-snapshot Initializing
property backups: Backups

Create, inspect, and delete backups of a serverless index.

Restoring one is not done from here: pass a backup_id to create_index_from_backup(), which creates a new index from it. For pod-based indexes the snapshot format is a collection, under collections.

Returns:

The Backups namespace.

Examples

list() returns one page, so follow pagination.next to read every backup:

>>> page = pc.backups.list()
>>> backups = list(page)
>>> while page.pagination and page.pagination.next:
...     page = pc.backups.list(pagination_token=page.pagination.next)
...     backups.extend(page)
>>> for backup in backups:
...     print(backup.backup_id, backup.source_index_name, backup.status)
bk-abc123 product-search Ready
bk-def456 product-search Ready
bk-ghi789 support-tickets Ready
property backup_schedules: BackupSchedules

Attach a recurring backup cadence to an index.

A schedule gives an index a daily, weekly, or monthly cadence, so Pinecone creates each backup for you rather than you triggering one every time.

Returns:

The BackupSchedules namespace.

Examples

iter_schedules() walks every page of an index’s schedules:

>>> for schedule in pc.backup_schedules.iter_schedules(index_name="product-search"):
...     print(schedule.name, schedule.frequency, schedule.enabled)
compliance-snapshots daily True
property restore_jobs: RestoreJobs

Track a restore that create_index_from_backup() started.

A restore job is the request itself, so it is what to follow when you passed timeout=-1 and the target index does not exist yet.

Returns:

The RestoreJobs namespace.

Examples

list() returns one page, and pages can overlap, so follow pagination.next and key the jobs by id:

>>> page = pc.restore_jobs.list()
>>> jobs = {job.restore_job_id: job for job in page}
>>> while page.pagination and page.pagination.next:
...     page = pc.restore_jobs.list(pagination_token=page.pagination.next)
...     jobs.update((job.restore_job_id, job) for job in page)
>>> for job in jobs.values():
...     print(job.restore_job_id, job.target_index_name, job.status)
rj-abc123 product-search-restored Completed
rj-def456 support-tickets-restored Pending
property inference: Inference

Embed text or images, and rerank documents, on hosted models.

Reach for this when you want vectors or relevance scores without hosting a model yourself.

Returns:

The Inference namespace.

Examples

multilingual-e5-large is asymmetric, so input_type tells it which side of a search the text belongs to — "passage" for text you intend to store, "query" for text you intend to search with:

>>> embeddings = pc.inference.embed(
...     model="multilingual-e5-large",
...     inputs=["Solar panels reduce energy costs and lower carbon emissions."],
...     parameters={"input_type": "passage"},
... )
>>> len(embeddings.data)
1
property assistants: Assistants

Create and manage Pinecone Assistants.

An assistant is a hosted, retrieval-augmented chat service: upload files to it and it answers questions grounded in their content, with no index or embedding pipeline of your own.

Returns:

The Assistants namespace.

Examples

>>> for assistant in pc.assistants.list():
...     print(assistant.name, assistant.status)
property assistant: _AssistantNamespaceProxy

Reach one assistant by name, or the whole namespace by attribute.

assistants is the canonical namespace; this singular alias is not deprecated. It forwards every attribute there, and calling it with a name is shorthand for describe().

Returns:

A proxy that behaves like the Assistants namespace for attribute access (pc.assistant.create(...)) and, when called with a name, returns that assistant’s details.

Examples

Calling the proxy with a name is shorthand for describe():

>>> bot = pc.assistant("acme-support-bot")
>>> bot.status
'Ready'

Every other attribute forwards to the plural namespace, so pc.assistant.create and pc.assistants.create are the same method reached two ways:

>>> new_bot = pc.assistant.create(
...     name="acme-billing-bot",
...     instructions="Help users with billing questions.",
... )
>>> new_bot.status
'Ready'
index(name: str = '', *, host: str = '', grpc: Literal[False] = False, pool_threads: int | None = None) → Index[source]
index(name: str = '', *, host: str = '', grpc: Literal[True], pool_threads: int | None = None) → GrpcIndex
index(name: str = '', *, host: str = '', grpc: bool, pool_threads: int | None = None) → Index | GrpcIndex

Open a data-plane client for one index, to read and write vectors.

A plain call, not a coroutine: it blocks while it resolves the host. An explicit host is used as-is, a name is served from this client’s host cache, and a name that misses the cache costs one describe request. The async twin, AsyncPinecone.index(), is a coroutine you await, and cannot return a gRPC client.

Parameters:
  • name (str) – Name of the index, e.g. "product-search". Costs one describe request the first time, then comes from the host cache.

  • host (str) – The index’s host, e.g. "product-search-abc123.svc.pinecone.io". Pass it when you have it already and the describe request is skipped entirely. A scheme you include is kept as given: "https://..." and a bare host both use TLS, while "http://..." is sent in cleartext and emits a RuntimeWarning unless the host is a loopback or RFC 1918 IP address, localhost, or *.localhost.

  • grpc (bool) – Return a GrpcIndex that carries data-plane operations over gRPC rather than HTTP. The scheme it dials comes from the grpc_scheme given to Pinecone. Defaults to False; see Using the gRPC client for when it pays off.

  • pool_threads (int | None) – Size of the thread pool backing async_req=True calls on the returned index. None (default) uses the client-level pool_threads. No effect when grpc=True.

Returns:

An Index over HTTP, or a GrpcIndex when grpc=True.

Raises:
  • PineconeValueError – If neither name nor host is given, or if name names an index that has no host yet — it is still initializing, so wait for its status to reach Ready.

  • NotFoundError – If name names no index in this project.

  • PineconeValueError – If grpc=True and the client’s proxy_url is not an http:// URL, raised before any describe request.

Return type:

Index | GrpcIndex

Examples

>>> idx = pc.index(name="product-search")

Passing the host skips the lookup, which saves a round trip when you already know it — from Indexes.describe, or from your own config:

>>> idx = pc.index(host="product-search-abc123.svc.pinecone.io")

Either form accepts grpc=True for the gRPC transport:

>>> idx = pc.index(name="product-search", grpc=True)

See also

indexes — the control-plane namespace, for creating, listing, describing, configuring, and deleting indexes rather than reading from one.

create_index_from_backup(*, name, backup_id, deletion_protection=None, tags=None, read_capacity=None, timeout=None)[source]

Create a new index by restoring from a backup.

Blocks and polls until the restored index is ready, unless timeout is -1. This is the only supported way to restore a backup: create() rejects source_backup_id= with a message pointing here.

Parameters:
  • name (str) – Name for the new index.

  • backup_id (str) – Identifier of the backup to restore from. Obtain it from Backups.create or Backups.list.

  • deletion_protection (DeletionProtection | str | None) – "enabled" or "disabled". Defaults to "disabled" server-side when omitted.

  • tags (Mapping[str, str] | None) – Optional key-value tags for the new index. When omitted, the server copies the backup’s own tags.

  • read_capacity (dict[str, Any] | None) – Optional read capacity for the restored index — {"mode": "OnDemand"} or {"mode": "Dedicated", "dedicated": {"node_type": ..., "scaling": "Manual", "manual": {"shards": ..., "replicas": ...}}}. Omitted entirely when None, leaving the server’s on-demand default in place. Serverless backups only; the server rejects a dedicated configuration too small to hold the backup.

  • timeout (int | None) – Seconds to wait for readiness. None (default) blocks up to 300 s. -1 returns a CreateIndexFromBackupResponse immediately (contains restore_job_id and index_id) without polling.

Returns:

A CreateIndexFromBackupResponse when timeout is -1 (contains restore_job_id and index_id), or an IndexModel describing the restored index once it is ready.

Raises:
Return type:

CreateIndexFromBackupResponse | IndexModel

Examples

The default form blocks until the restored index is ready and hands back the index itself, so the next call can use it:

>>> index = pc.create_index_from_backup(
...     name="product-search-restored",
...     backup_id="bk-abc123",
... )
>>> index.status.state
'Ready'

timeout=-1 returns as soon as the restore is accepted. What comes back is a CreateIndexFromBackupResponse, not an index — the index does not exist yet, so follow the restore through pc.restore_jobs rather than treating the return value as one:

>>> result = pc.create_index_from_backup(
...     name="product-search-restored",
...     backup_id="bk-abc123",
...     timeout=-1,
... )
>>> job = pc.restore_jobs.describe(job_id=result.restore_job_id)
>>> job.status
'Completed'

A restore can land straight onto dedicated read nodes instead of the on-demand default:

>>> index = pc.create_index_from_backup(
...     name="product-search-restored",
...     backup_id="bk-abc123",
...     read_capacity={
...         "mode": "Dedicated",
...         "dedicated": {
...             "node_type": "t1",
...             "scaling": "Manual",
...             "manual": {"shards": 2, "replicas": 2},
...         },
...     },
... )
>>> index.status.state
'Ready'

Changed in version 10.0: Added read_capacity, so a restore can land straight onto dedicated read nodes instead of defaulting to on-demand capacity.

property config: PineconeConfig

Read back the settings this client resolved at construction.

Returns:

PineconeConfig carrying the resolved API key, host, timeout, and connection settings.

Examples

The values are post-resolution, with defaults and environment variables folded in, so this is where to confirm which host a client is actually pointed at:

>>> pc.config.host
'https://api.pinecone.io'
>>> pc.config.timeout
30.0
close()[source]

Release this client’s control-plane connections.

Closes the control-plane connection pool, plus the inference and assistants pools if those namespaces were used. Index clients from index() hold their own connections and are not closed here. Prefer the context manager form, with Pinecone(...) as pc:, which calls this on the way out.

Examples

The context manager form closes the client on the way out, on an exception as well as on a normal exit:

>>> from pinecone import Pinecone
>>> with Pinecone(api_key="your-api-key") as client:
...     for index in client.indexes.list():
...         print(index.name)

Close it yourself when the client has to outlive a single block:

>>> client = Pinecone(api_key="your-api-key")
>>> try:
...     print(client.indexes.exists("product-search"))
... finally:
...     client.close()
True
Return type:

None

Indexes

class pinecone.client.indexes.Indexes(http, host_cache=None)[source]

Bases: object

Control-plane operations for Pinecone indexes.

An index is the container your records live in: its searched fields are declared as a schema when you create it, and every query is aimed at one index. Reached as pc.indexes; not constructed directly.

The backup methods here are scoped to a single index. Backups (pc.backups) covers the project-wide backup listing plus delete, which belong to no one index.

Examples

from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")
names = [index.name for index in pc.indexes.list()]

See also

Pinecone.index(name), the data-plane client for reads and writes against one index.

Error handling, the exceptions any method here can raise and how to handle them.

Changed in version 10.0: Graduated to the schema-based API. create() takes schema=/deployment= instead of spec=/dimension=/ metric=/vector_type=; configure() nests pod scaling under deployment= and dropped embed=; list() returns a Paginator; the index-scoped backup methods graduated from the preview namespace.

Parameters:
  • http (HTTPClient)

  • host_cache (dict[str, str] | None)

__init__(http, host_cache=None)[source]
Parameters:
  • http (HTTPClient)

  • host_cache (dict[str, str] | None)

Return type:

None

list(*, limit=None, pagination_token=None)[source]

List every index in the project.

Parameters:
  • limit (int | None) – Maximum number of indexes to yield. Must be a positive integer; None (the default) yields every index.

  • pagination_token (str | None) – Accepted so this listing shares the paginator interface of the other listings. The server issues no pagination token for indexes, so leave it None.

Returns:

Paginator over IndexModel instances.

Raises:

PineconeValueError – If limit is zero or negative.

Return type:

Paginator[IndexModel]

Examples

>>> for index in pc.indexes.list():
...     print(index.name, index.status.state)

Changed in version 10.0: Returns a Paginator instead of an IndexList. Iteration keeps working; replace pc.indexes.list().names() with [index.name for index in pc.indexes.list()].

describe(name)[source]

Get detailed information about a named index.

Caches the index’s host, so a later Pinecone.index(name) call for the same name skips its own describe round trip.

Parameters:

name (str) – The name of the index to describe.

Returns:

IndexModel with name, host, schema, deployment, read_capacity, status, deletion_protection, and tags.

Raises:
Return type:

IndexModel

Examples

The returned host carries the https:// scheme:

>>> index = pc.indexes.describe("my-index")
>>> index.host
'https://my-index-abc123.svc.pinecone.io'
exists(name)[source]

Check whether a named index exists.

Calls describe() internally and returns False instead of raising when the index isn’t found. Every other error propagates.

Parameters:

name (str) – The name of the index to check.

Returns:

True if the index exists, False otherwise.

Raises:
Return type:

bool

Examples

>>> pc.indexes.exists("my-index")
True

Changed in version 10.0: An empty name now raises PineconeValueError instead of returning False.

delete(name, *, timeout=None)[source]

Delete an index by name.

Blocks until the index is gone, with no upper time bound unless you pass timeout.

Parameters:
  • name (str) – The name of the index to delete.

  • timeout (int | None) – Seconds to wait for the index to disappear. Use None (default) to poll indefinitely until the index is gone. Use a positive int to poll with a deadline. Use -1 to return immediately without polling.

Raises:
Return type:

None

Examples

Delete an index and block until it is gone:

pc.indexes.delete("my-index")

Or bound the wait, so an index still present after a minute raises PineconeTimeoutError instead of polling forever:

pc.indexes.delete("my-index", timeout=60)

Passing timeout=-1 returns as soon as the delete request is accepted, without polling; the index is still being torn down when the call returns.

create(*, schema=None, name=None, deployment=None, read_capacity=None, deletion_protection=None, tags=None, cmek_id=None, timeout=None, spec=None, dimension=None, metric=None, vector_type=None, **legacy_kwargs)[source]

Create a new index.

An index’s field layout is declared as a schema of named, typed fields. Every field in the schema must be a searched field: dense_vector, sparse_vector, or string with full_text_search, embed or sparse_embed. A string field with embed or sparse_embed supports integrated embedding: Pinecone embeds its text on write and the query text on search. The result is a document index; read and write it through index.documents. Metadata-only fields aren’t declared here; they’re indexed automatically the first time they appear on an upserted record. The schema can’t change once the index exists, and the call blocks until the index is ready unless you pass timeout=-1.

Parameters:
  • schema (dict[str, Any] | IndexSchema | None) –

    The index’s field schema. Required unless the deprecated dimension= (with optional metric=/ vector_type=) is used instead; the two are mutually exclusive. A dict with a "fields" key mapping field names to typed configurations:

    {
        "fields": {
            "your_vector": {"type": "dense_vector",
                            "dimension": 1536, "metric": "cosine"},
            "body": {"type": "string",
                     "full_text_search": {"language": "en",
                                          "stemming": True}},
        }
    }
    

    Also accepts the dict produced by SchemaBuilder or an IndexSchema. A hybrid index has to declare its sparse_vector field here; see the note after the examples. full_text_search.language accepts a fixed set of language codes (or their English names, default en), but stop_words=True is not supported for every language: the server’s 400 names the unsupported language, by its English name rather than the code you sent.

  • name (str | None) – Name for the index, in lowercase alphanumerics and hyphens, e.g. "movie-recommendations". The server assigns a name when omitted.

  • deployment (dict[str, Any] | None) – Deployment configuration, discriminated on "deployment_type". For a managed index: {"deployment_type": "managed", "cloud": "aws", "region": "us-east-1"}. For a pod-based index, "deployment_type": "pod" plus environment, pod_type, replicas, and shards. Defaults to a managed index on AWS us-east-1 when omitted. Mutually exclusive with the deprecated spec=.

  • read_capacity (dict[str, Any] | None) – Read capacity for a managed or BYOC index, either {"mode": "OnDemand"} or {"mode": "Dedicated", "dedicated": {"node_type": ..., "scaling": ..., "manual": {"replicas": ..., "shards": ...}}}.

  • deletion_protection (str | None) – "enabled" to block delete() on this index until it’s set back to "disabled" (the default).

  • tags (Mapping[str, str] | None) – Key-value tags to attach, e.g. {"env": "prod"}. Pass None (the default) to attach none.

  • cmek_id (str | None) – ID of a customer-managed encryption key to encrypt the index with, e.g. "key-abc123".

  • timeout (int | None) – Seconds to wait for the index to become ready before returning. None (default) waits indefinitely, -1 returns immediately without waiting, and a positive number waits up to that many seconds. Any other negative value raises PineconeValueError before a request is sent.

  • spec (Any) –

    Deprecated. A ServerlessSpec, PodSpec, ByocSpec, or the equivalent dict, translated into deployment= (and read_capacity= when the spec carries one). Mutually exclusive with deployment=. Use create_for_model() for IntegratedSpec.

    Deprecated since version 10.0: Pass deployment= directly instead.

  • dimension (int | None) –

    Deprecated. Dense vector width for the legacy path, translated into a single-field schema=. Required when creating a dense index this way.

    Deprecated since version 10.0: Declare a named field in schema= instead.

  • metric (Metric | str | None) –

    Deprecated. Similarity metric for the legacy dense path: "cosine" (default), "euclidean", or "dotproduct".

    Deprecated since version 10.0: Set metric inside the schema= field declaration instead.

  • vector_type (VectorType | str | None) –

    Deprecated. "dense" (default) or "sparse", for the legacy path.

    Deprecated since version 10.0: Declare a named dense_vector/sparse_vector field in schema= instead.

  • legacy_kwargs (Any)

Returns:

IndexModel describing the created index, ready unless timeout=-1 was passed.

Raises:
  • PineconeValueError – If neither schema= nor dimension= is given, or mutually exclusive arguments (schema= with a legacy vector kwarg, or deployment= with spec=) are combined, or timeout is a negative value other than -1.

  • PineconeTypeError – If an unsupported legacy keyword (e.g. pods=) or spec=IntegratedSpec(...) is passed.

  • IndexInitFailedError – If the index fails to initialize.

  • PineconeTimeoutError – If the index isn’t ready before timeout elapses.

Return type:

IndexModel

Examples

A dense index on the default deployment (managed, AWS us-east-1). The call waits for the index to become ready before returning:

>>> index = pc.indexes.create(
...     name="movie-recommendations",
...     schema={"fields": {"your_vector": {
...         "type": "dense_vector", "dimension": 1536, "metric": "cosine"}}},
... )
>>> index.status.ready
True

A hybrid index in a region of your choosing. Declare the sparse_vector field now; see the note below:

>>> index = pc.indexes.create(
...     name="support-articles",
...     schema={"fields": {
...         "your_vector": {"type": "dense_vector",
...                         "dimension": 1024, "metric": "cosine"},
...         "keywords": {"type": "sparse_vector"},
...         "body": {"type": "string",
...                  "full_text_search": {"language": "en",
...                                       "stemming": True}},
...     }},
...     deployment={"deployment_type": "managed",
...                 "cloud": "aws", "region": "us-west-2"},
...     tags={"env": "prod"},
... )

Integrated embedding on a string field, processed in the US for both documents and queries:

>>> index = pc.indexes.create(
...     name="support-articles-us",
...     schema={"fields": {"body": {
...         "type": "string",
...         "embed": {
...             "model": "text-embedding-3-large",
...             "processing_location": "us",
...         },
...     }}},
... )

Note

A hybrid index must declare its sparse_vector field explicitly. A dense field with metric="dotproduct" does not accept sparse values on its own: the create succeeds, and only the sparse upserts are refused later. The field cannot be added by configure(), so an index created without one has to be recreated. See Migrating to V10.

See also

create_for_model() creates a legacy integrated index, which requires the legacy Records API. For integrated embedding in a document index, declare embed / sparse_embed on a string field here instead.

Changed in version 10.0: spec=, dimension=, metric=, and vector_type= are deprecated, keyword-only sugar for the current schema=/ deployment= arguments. pods=, metadata_config=, source_collection=, source_backup_id=, and spec=IntegratedSpec(...) have no equivalent here; use create_for_model() for a legacy integrated index, or embed / sparse_embed on a string field for integrated embedding in a document index.

create_for_model(*, name, cloud, region, embed, deletion_protection=None, tags=None, schema=None, read_capacity=None, timeout=None)[source]

Create a legacy integrated index, served by the legacy Records API.

Pinecone embeds text written to the mapped field automatically at upsert time and embeds queries at read time using the same model. In the returned index, the embedding configuration surfaces as a semantic_text field in schema, named after the field_map text entry.

This creates a legacy integrated index, and legacy integrated indexes require the legacy Records API (upsert_records() and search()). For new work, create a document index with integrated embedding instead: pass create() a string field with embed or sparse_embed and use index.documents, which adds full-text search on the same fields and score_by.

Parameters:
  • name (str) – Name for the index, in lowercase alphanumerics and hyphens, e.g. "semantic-search".

  • cloud (str) – Public cloud provider: "aws", "gcp", or "azure".

  • region (str) – Cloud region, e.g. "us-east-1".

  • embed (Mapping[str, Any] | Any) – Embedding configuration. A dict (or EmbedConfig / IndexEmbed) with required model and field_map (e.g. {"text": "chunk_text"}) and optional metric, dimension, read_parameters, write_parameters. The model cannot be changed after creation.

  • deletion_protection (str | None) – "enabled" to block delete() on this index until it’s set back to "disabled" (the default).

  • tags (Mapping[str, str] | None) – Key-value tags to attach, e.g. {"env": "prod"}. Pass None (the default) to attach none.

  • schema (dict[str, Any] | None) – Filterable metadata fields, e.g. {"fields": {"genre": {"filterable": True}}}. A bare field map is wrapped in {"fields": ...} for you.

  • read_capacity (dict[str, Any] | None) – Read capacity for the index, in the same shape as for create().

  • timeout (int | None) – Seconds to wait for the index to become ready before returning. None (default) waits indefinitely, -1 returns immediately without waiting, and a positive number waits up to that many seconds. Any other negative value raises PineconeValueError before a request is sent.

Returns:

IndexModel describing the created index, ready unless timeout=-1 was passed.

Raises:

PineconeValueError – If name, cloud, region, embed, tags, deletion_protection, or timeout (a negative value other than -1) fail client-side validation.

Return type:

IndexModel

Examples

The field_map text entry names the record field Pinecone embeds, and that same name is what the field is called in the returned schema (chunk_text below):

>>> index = pc.indexes.create_for_model(
...     name="semantic-search",
...     cloud="aws",
...     region="us-east-1",
...     embed={"model": "multilingual-e5-large",
...            "field_map": {"text": "chunk_text"}},
... )
>>> index.schema.fields["chunk_text"].model
'multilingual-e5-large'

See also

create() creates an index you supply the vectors for yourself, declaring them as dense_vector/sparse_vector fields in schema=.

configure(name, *, deployment=None, schema=None, read_capacity=None, deletion_protection=None, tags=None, replicas=None, pod_type=None, serverless_read_capacity=None, **legacy_kwargs)[source]

Configure an existing index.

Only the fields you provide are updated; omitted parameters are left unchanged on the server. Read capacity and pod scaling apply asynchronously, so the call returns while the change is still in flight.

Parameters:
  • name (str) – Name of the index to configure.

  • deployment (dict[str, Any] | None) – Pod-scaling updates for pod-based indexes: {"replicas": int, "pod_type": str} (either or both). Only those two keys are accepted; any other key is rejected by the server. "deployment_type" raises PineconeValueError client-side, since deployment type, cloud/region, and environment cannot be changed after creation.

  • schema (dict[str, Any] | IndexSchema | None) – Schema updates. On an index created with create(schema=...) the schema is fixed: nothing in it can be changed, including the embed/sparse_embed parameters of a string field. On an index created with create_for_model(), only semantic_text field parameters (read_parameters/write_parameters) can be updated; see the note after the examples.

  • read_capacity (dict[str, Any] | None) – Updated read capacity dict, either {"mode": "OnDemand"} or {"mode": "Dedicated", "dedicated": {...}}. Applies to managed and BYOC indexes.

  • deletion_protection (str | None) – "enabled" to block delete() on this index, "disabled" to allow it again.

  • tags (Mapping[str, str] | None) – Tag updates, merged into the index’s existing tags. Set a value to "" to delete that key; keys you don’t mention stay unchanged. The server applies its tag limit to the merged total, so adding tags to an index that already carries several can be rejected. {} is rejected client-side.

  • replicas (int | None) – Deprecated. Legacy pod-scaling replica count, translated into deployment={"replicas": ...}. Mutually exclusive with deployment.

  • pod_type (PodType | str | None) – Deprecated. Legacy pod type, translated into deployment={"pod_type": ...} alongside replicas. Mutually exclusive with deployment.

  • serverless_read_capacity (dict[str, Any] | None) – Deprecated. Legacy read-capacity keyword for managed indexes, translated straight into read_capacity. Mutually exclusive with read_capacity.

  • legacy_kwargs (Any)

Returns:

IndexModel reflecting the updated index state. Read status for how far an asynchronous change has got rather than assuming it landed.

Raises:
  • PineconeValueError – If name is empty, all kwargs are None, any dict kwarg is empty, deployment includes deployment_type, tags/deletion_protection are invalid, or deployment/read_capacity is combined with the deprecated keyword argument it translates to.

  • PineconeTypeError – If name is not a str, or if embed= or spec= is passed (neither has a translation here; the message shows the equivalent current call where one exists).

  • NotFoundError – If the index does not exist.

  • ApiError – Typically status 422 or 400, if schema is passed for an index created with create(schema=...) (even unchanged fields are refused), or if deployment has a key other than replicas or pod_type. The message comes from the server and can read as a raw deserialization error rather than naming the field.

Return type:

IndexModel

Examples

Scale a pod-based index. Pod scaling is applied in the background, so read index.status on the returned model to see how far the change has got rather than assuming it landed:

>>> index = pc.indexes.configure(
...     "legacy-recommender", deployment={"replicas": 4, "pod_type": "p1.x2"}
... )

Tag updates merge into the tags the index already carries. Given an index tagged {"env": "staging", "team": "search"}, the call below sets env, deletes team (an empty value removes a key), and leaves every other tag as it was, so index.tags comes back {"env": "prod"}:

>>> index = pc.indexes.configure("my-index", tags={"env": "prod", "team": ""})

Note

Only semantic_text field parameters (read_parameters/ write_parameters) can be updated through schema=; other field types can’t be added, removed, or retyped after creation. Since create() cannot declare a semantic_text field directly, this only applies to indexes created with create_for_model(). On an index created with create(schema=...) the schema is fixed, and passing schema= is rejected.

Changed in version 10.0: Before/after:

# 9.x
pc.indexes.configure("my-index", replicas=4, pod_type="p1.x2")
# 10.x
pc.indexes.configure("my-index",
                     deployment={"replicas": 4, "pod_type": "p1.x2"})

embed= is gone entirely, along with the convert-to-integrated flow it drove; replicas=/pod_type=/ serverless_read_capacity= remain as deprecated keyword-only sugar for deployment=/read_capacity=; and the method returns the updated IndexModel instead of None.

Deprecated since version 10.0: replicas=, pod_type=, and serverless_read_capacity= are translated into deployment=/read_capacity= rather than sent as-is, and cannot be combined with the argument they translate to; passing both raises PineconeValueError. New code should use deployment=/read_capacity= directly.

create_backup(index_name, *, name=None, description=None)[source]

Create a backup of an index.

Index-scoped shortcut for Backups.create, which does the same thing; the difference is that this one takes the index name positionally.

Parameters:
  • index_name (str) – Name of the index to back up.

  • name (str | None) – Your own name for the backup, e.g. "nightly-20240115". Omit it and the server assigns one.

  • description (str | None) – Free-text note stored with the backup, e.g. "pre-reindex snapshot".

Returns:

BackupModel describing the new backup. status is typically "Initializing" right after creation; poll describe_backup() until it reads "Ready" before restoring from it.

Raises:
Return type:

BackupModel

Examples

>>> backup = pc.indexes.create_backup("my-index", name="nightly-20240115")
>>> backup.backup_id
'bk-abc123'

Added in version 10.0: Graduated from pc.preview.indexes.create_backup, now returning the single top-level BackupModel.

list_backups(index_name, *, limit=None, pagination_token=None, include_deleted=None)[source]

List the backups of one index, following pages as you iterate.

Parameters:
  • index_name (str) – Name of the index whose backups to list.

  • limit (int | None) – Maximum number of backups to yield across all pages. Must be a positive integer. None yields all backups. It also sets the requested page size, but only on a request that carries no pagination token: every later page is sized by the token, which already encodes it.

  • pagination_token (str | None) – Token from an earlier call, to resume where that call stopped. limit still caps the total yield, but it is not sent alongside a token (see above). See Pagination.

  • include_deleted (bool | None) – When True, include backups of every index that has ever used index_name, deleted ones included; those backups carry a non-None source_index_deleted_at. When None (the default) the parameter is omitted entirely and the server’s default (false) applies.

Returns:

Paginator over BackupModel instances.

Raises:
  • PineconeValueError – If index_name is empty or limit is zero or negative.

  • PineconeTypeError – If index_name is not a str.

  • NotFoundError – If index_name does not resolve to an active index, which is not the same as the name being unknown; see the note after the examples.

Return type:

Paginator[BackupModel]

Examples

>>> for backup in pc.indexes.list_backups("my-index"):
...     print(backup.backup_id, backup.status)
bk-abc123 Ready

Once every index that used a name has been deleted, that name’s backups come back only with include_deleted=True; without it this raises NotFoundError. They are the ones carrying a source_index_deleted_at:

>>> backups = pc.indexes.list_backups(
...     "legacy-catalog", include_deleted=True
... ).to_list()
>>> [b.backup_id for b in backups if b.source_index_deleted_at]
['bk-old111']

Important

NotFoundError here does not necessarily mean index_name was never used. With include_deleted omitted or False, index_name must resolve to an active index: if every index that used the name has since been deleted, this raises NotFoundError rather than returning an empty list. Retry with include_deleted=True to get those backups back; a NotFoundError there means the name was never used in this project.

See also

Backups.list is the project-wide listing, where the index name is an optional filter. It hands back one page for you to drive the token yourself, rather than a paginator that follows the pages for you.

Added in version 10.0: Graduated from pc.preview.indexes.list_backups, and gained include_deleted.

describe_backup(backup_id)[source]

Describe a backup by its ID.

Backups are identified independently of any index, so despite living on indexes this takes a backup ID rather than an index name.

Parameters:

backup_id (str) – Identifier of the backup to describe, as returned in backup_id by create_backup().

Returns:

BackupModel with the current state of the backup.

Raises:
Return type:

BackupModel

Examples

>>> backup = pc.indexes.describe_backup("bk-abc123")
>>> backup.status
'Ready'

See also

Backups.describe is the same lookup reached through pc.backups, which takes backup_id as a keyword argument rather than positionally.

Added in version 10.0: Graduated from pc.preview.indexes.describe_backup.

Collections

class pinecone.client.collections.Collections(http)[source]

Bases: object

Control-plane operations for Pinecone collections.

A collection is a static, point-in-time copy of a pod-based index’s vector data, held outside the index. Reach it as pc.collections; not constructed directly: Pinecone builds and caches its own instance on first access.

Collections are the snapshot mechanism for pod-based indexes; Backups is the one for serverless and BYOC indexes. The difference that decides which you want is restore: a backup can be restored into a new index with create_index_from_backup(), and this SDK cannot restore a collection: only API versions before 2026-07 create an index from one.

Examples

>>> for col in pc.collections.list():
...     print(col.name, col.status)
movie-embeddings-snapshot Ready
product-catalog-snapshot Initializing

See also

Backups, the equivalent for serverless and BYOC indexes, and the only snapshot this SDK can restore.

Parameters:

http (HTTPClient)

__init__(http)[source]
Parameters:

http (HTTPClient)

Return type:

None

create(*, name, source)[source]

Create a collection from an existing pod-based index.

A collection is a static copy of an index’s vector data, held outside the index as a snapshot of its contents at the moment it was taken. Only a pod-based index can be used as a source, and it must already be ready. The call returns as soon as creation starts; it does not wait for the collection to become ready.

Parameters:
  • name (str) – Name for the new collection: lowercase alphanumeric characters and hyphens, not starting or ending with a hyphen (e.g. "movie-embeddings-snapshot").

  • source (str) – Name of the pod-based index to copy.

Returns:

CollectionModel whose status is "Initializing" until the snapshot has been built.

Raises:
Return type:

CollectionModel

Examples

The collection is still being built when the call returns, so its status is "Initializing" rather than "Ready":

>>> col = pc.collections.create(
...     name="movie-embeddings-snapshot", source="movie-recommendations"
... )
>>> col.status
'Initializing'

There is no timeout= argument to wait on. Poll describe() until the status leaves "Initializing", then read col.status to see where it settled:

>>> import time
>>> while col.status == "Initializing":
...     time.sleep(5)
...     col = pc.collections.describe(col.name)
>>> col.status
'Ready'

Note

This SDK cannot create an index from a collection; only API versions before 2026-07 can. Indexes.create() rejects source_collection with a PineconeTypeError in both spellings: as a top-level keyword argument, and nested in a PodSpec passed to the deprecated spec= argument. If you need a snapshot you can restore, back up a serverless index with Backups.create() and restore it with create_index_from_backup().

See also

Backups.create(), the serverless equivalent, whose snapshot can be restored into a new index.

list()[source]

List every collection in the project.

There’s no filtering, sorting, or pagination; all collections come back at once.

Returns:

CollectionList, which supports iteration, len(), index access, and a names() convenience method.

Return type:

CollectionList

Examples

>>> collections = pc.collections.list()
>>> collections.names()
['movie-embeddings-snapshot', 'product-catalog-snapshot']
>>> for col in collections:
...     print(col.name, col.status)
movie-embeddings-snapshot Ready
product-catalog-snapshot Initializing

See also

Backups.list() lists snapshots of serverless and BYOC indexes, and unlike this one is paginated.

describe(name)[source]

Get details about a collection.

Parameters:

name (str) – Name of the collection to describe.

Returns:

CollectionModel with name, status, environment, size (bytes on disk), dimension, and vector_count.

Raises:
Return type:

CollectionModel

Examples

size is how much space the snapshot occupies, in bytes, not the dimension of its vectors. It, dimension, and vector_count are None until the collection finishes initializing:

>>> desc = pc.collections.describe("movie-embeddings-snapshot")
>>> print(desc.status, desc.dimension, desc.vector_count, desc.size)
Ready 1024 99 3126700

See also

Backups.describe(), the serverless equivalent, which reports record_count and size_bytes instead.

delete(name)[source]

Delete a collection permanently.

Deletion is asynchronous: the call returns as soon as the request is accepted, and the collection can still show up in list() for a short time afterwards. While a collection is still being created or deleted, the server refuses to delete its source index.

Parameters:

name (str) – Name of the collection to delete.

Raises:
Return type:

None

Examples

>>> pc.collections.delete("movie-embeddings-snapshot")

See also

Backups.delete(), the serverless equivalent, which takes a backup_id rather than a name.

Backups

class pinecone.client.backups.Backups(http)[source]

Bases: object

Stored, point-in-time snapshots of a serverless or BYOC index.

A backup captures an index’s records and schema so that a new index can be created from it later with create_index_from_backup(). Backups are identified by a backup_id and outlive the index they were taken from. Reached as pc.backups; not constructed directly.

Pod-based indexes cannot be backed up; their snapshot mechanism is Collections.

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> page = pc.backups.list(limit=100)
>>> [b.backup_id for b in page]
['bk-abc123', 'bk-def456']

See also

  • list_backups(), the index-scoped listing, which walks every page for you.

  • Error handling, for the exceptions these methods raise and which ones to retry.

Parameters:

http (HTTPClient)

__init__(http)[source]
Parameters:

http (HTTPClient)

Return type:

None

create(*, index_name, name=None, description=None)[source]

Create a backup of an existing index.

Only serverless and BYOC indexes can be backed up. The call returns as soon as the server accepts the request, not when the backup is ready.

Parameters:
  • index_name (str) – Name of the index to back up.

  • name (str | None) – Name for the backup, e.g. "daily-20240115". When omitted, the backup has no name and is identified only by its backup_id.

  • description (str | None) – Description for the backup.

Returns:

A BackupModel describing the new backup, with status "Initializing". Poll describe() to follow it.

Raises:
  • PineconeValueError – If index_name is empty.

  • PineconeTypeError – If index_name is not a str.

  • ForbiddenError – If the organization’s plan does not include backups.

  • NotFoundError – If index_name does not resolve to an index in this project.

  • ApiError – If index_name names a pod-based index, which is snapshotted into a collection rather than a backup.

Return type:

BackupModel

Examples

Poll describe() until the status leaves "Initializing". A backup that fails settles on "InitializationFailed", so waiting for "Ready" alone could loop forever.

>>> import time
>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> backup = pc.backups.create(index_name="product-search")
>>> while backup.status == "Initializing":
...     time.sleep(10)
...     backup = pc.backups.describe(backup_id=backup.backup_id)
>>> backup.backup_id
'bk-abc123'
>>> backup.status
'Ready'

Give the backup a name and description so a later listing identifies it by more than its backup_id:

>>> backup = pc.backups.create(
...     index_name="product-search",
...     name="daily-20240115",
...     description="Scheduled daily backup before reindexing",
... )
>>> backup.name
'daily-20240115'

See also

list(*, index_name=None, limit=None, pagination_token=None, include_deleted=None)[source]

List one page of backups.

When index_name is given, lists backups of that index only; otherwise lists every backup in the project. One call returns one page, and iterating the result does not fetch the next one. Follow pagination.next yourself (see Pagination), or use list_backups(), which walks every page of one index’s backups for you.

Parameters:
  • index_name (str | None) – Index name to scope the listing to, or None for every backup in the project.

  • limit (int | None) – Maximum number of results per page, e.g. 100. When None, the server applies its default. The SDK drops limit when pagination_token is given, because the token already carries the page size.

  • pagination_token (str | None) – Token for the next page, taken from BackupList.pagination.next.

  • include_deleted (bool | None) – When True, include backups of every index that has ever used index_name, including deleted ones. Defaults to the server’s behavior, which excludes them. Only valid together with index_name.

Returns:

A BackupList holding one page, supporting iteration, len(), and index access. pagination is None on the final page. Backups created or deleted during a walk can shift later pages, so de-duplicate by backup_id.

Raises:
Return type:

BackupList

Examples

Passing index_name scopes the listing to one index:

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> for backup in pc.backups.list(index_name="product-search"):
...     print(backup.name, backup.status)
daily-20240115 Ready

Walk every page of the project-wide listing:

>>> page = pc.backups.list(limit=100)
>>> backups = list(page)
>>> while page.pagination and page.pagination.next:
...     page = pc.backups.list(pagination_token=page.pagination.next)
...     backups.extend(page)
>>> [b.backup_id for b in backups]
['bk-abc123', 'bk-def456', 'bk-ghi789']

Pass include_deleted=True to reach the backups of an index you have already deleted:

>>> orphaned = pc.backups.list(
...     index_name="legacy-catalog", include_deleted=True
... )
>>> [b.backup_id for b in orphaned if b.source_index_deleted_at]
['bk-old111']

Note

If every index that used index_name has been deleted, listing without include_deleted raises NotFoundError rather than returning an empty list. Pass include_deleted=True to see their backups.

Changed in version 10.0: Added include_deleted. BackupModel now carries source_index_deleted_at instead of dimension/metric.

describe(*, backup_id)[source]

Get the current state of one backup.

Parameters:

backup_id (str) – The identifier of the backup to describe.

Returns:

A BackupModel whose status is "Initializing", "Ready", or "InitializationFailed", alongside the source_index_name it was taken from, the captured schema, and the record_count and size_bytes of the snapshot.

Raises:
Return type:

BackupModel

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> backup = pc.backups.describe(backup_id="bk-abc123")
>>> backup.status
'Ready'
>>> backup.source_index_name
'product-search'

See also

describe_backup(), the same call under the indexes namespace.

get(*, backup_id)[source]

Get detailed information about a backup (alias for describe()).

Parameters:

backup_id (str) – The identifier of the backup.

Returns:

A BackupModel whose status is "Initializing", "Ready", or "InitializationFailed", alongside the source_index_name it was taken from, the captured schema, and the record_count and size_bytes of the snapshot.

Raises:
Return type:

BackupModel

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> backup = pc.backups.get(backup_id="bk-abc123")
>>> backup.status
'Ready'
>>> backup.source_index_name
'product-search'
delete(*, backup_id)[source]

Delete a backup.

Parameters:

backup_id (str) – The identifier of the backup to delete.

Raises:
Return type:

None

Examples

Deleting a backup leaves its source index, other backups of that index, and any index restored from it untouched:

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> pc.backups.delete(backup_id="bk-abc123")

BackupSchedules

class pinecone.client.backup_schedules.BackupSchedules(http)[source]

Bases: object

Recurring, time-based backups of a single index.

A schedule snapshots its index on a fixed cadence and retains each backup for a set number of days, so you do not have to call create() on a timer of your own. Reached as pc.backup_schedules; not constructed directly.

At most one schedule per index can be enabled at a time. The backups a schedule produces are ordinary backups: read one with describe(), or list a schedule’s own runs with history().

Note

Backups are a plan entitlement. A project without it gets ForbiddenError, not NotFoundError, even for a schedule that does not exist. On-demand backups need the same entitlement.

Examples

Back up an index every day and keep each backup for 90 days:

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> schedule = pc.backup_schedules.create(
...     index_name="product-search",
...     name="compliance-snapshots",
...     frequency="daily",
...     retention_days=90,
... )
>>> print(schedule.schedule_id, schedule.next_scheduled_run)
e88f7273-42aa-47e9-af73-593827136867 2026-04-03 06:00:00+00:00

See also

Error handling for the exceptions these methods raise and which ones are worth retrying.

Parameters:

http (HTTPClient)

__init__(http)[source]
Parameters:

http (HTTPClient)

Return type:

None

create(*, index_name, name, frequency, retention_days)[source]

Create a time-based backup schedule for an index.

The schedule is created enabled, with its first run already planned. For a single backup taken now, use create() instead.

Parameters:
  • index_name (str) – Name of the serverless or BYOC index to back up, for example "product-search".

  • name (str) – Name for the schedule, for example "compliance-snapshots". Each backup it produces is named "{name}-{run timestamp}", such as "compliance-snapshots-20260403T060000Z".

  • frequency (str) – How often to back up the index: "daily", "weekly", or "monthly".

  • retention_days (int) – Days to keep each backup this schedule produces. Must be at least 1; the server enforces the maximum.

Returns:

A BackupScheduleModel for the new schedule, with next_scheduled_run set. The retention window comes back as retention_expire_after_days.

Raises:
  • PineconeValueError – If index_name or name is empty, if frequency is not a supported cadence, or if retention_days is less than 1.

  • PineconeTypeError – If index_name or name is not a str.

  • ForbiddenError – If the project’s plan does not include scheduled backups.

  • NotFoundError – If the index does not exist.

  • ConflictError – If the index already has an enabled schedule. Disable or delete that one first.

  • ApiError – If index_name names a pod-based index, which cannot be scheduled.

Return type:

BackupScheduleModel

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> schedule = pc.backup_schedules.create(
...     index_name="product-search",
...     name="compliance-snapshots",
...     frequency="daily",
...     retention_days=90,
... )
>>> print(schedule.schedule_id, schedule.next_scheduled_run)
e88f7273-42aa-47e9-af73-593827136867 2026-04-03 06:00:00+00:00
list(*, index_name, limit=None, pagination_token=None)[source]

List one page of an index’s backup schedules.

Disabled schedules are included, so an index can list several schedules even though at most one is enabled. To walk every page, use iter_schedules(); see Pagination.

Parameters:
  • index_name (str) – Name of the index whose schedules to list.

  • limit (int | None) – Maximum results per page, for example 20. None uses the server’s page size. Ignored when pagination_token is set, because the token carries its own page size.

  • pagination_token (str | None) – The pagination.next value from the previous page, or None for the first page.

Returns:

A BackupScheduleList of BackupScheduleModel that supports iteration, len(), and index access. Its pagination is None on the last page.

Raises:
Return type:

BackupScheduleList

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> schedules = pc.backup_schedules.list(index_name="product-search")
>>> schedules.names()
['compliance-snapshots']
>>> [s.schedule_id for s in schedules.enabled_schedules()]
['e88f7273-42aa-47e9-af73-593827136867']

names() and enabled_schedules() read only this page, so check schedules.pagination before concluding that an index has no enabled schedule.

iter_schedules(*, index_name, limit=None, pagination_token=None)[source]

Iterate every backup schedule on an index, fetching pages on demand.

The auto-paginating twin of list().

Parameters:
  • index_name (str) – Name of the index whose schedules to iterate.

  • limit (int | None) – Maximum number of schedules to yield across all pages. Must be positive. None yields all of them.

  • pagination_token (str | None) – Token to resume from a previous call. limit still caps the total yield.

Returns:

A Paginator over BackupScheduleModel instances.

Raises:
  • PineconeValueError – If index_name is empty or limit is zero or negative. Raised as soon as you call this method, before the first page is fetched.

  • PineconeTypeError – If index_name is not a str.

  • ForbiddenError – If the project’s plan does not include scheduled backups. Raised while iterating, when a page is fetched.

  • NotFoundError – If the index does not exist.

Return type:

Paginator[BackupScheduleModel]

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> for s in pc.backup_schedules.iter_schedules(index_name="product-search"):
...     print(s.schedule_id, s.frequency, s.enabled)
e88f7273-42aa-47e9-af73-593827136867 daily True
describe(*, schedule_id)[source]

Get the current configuration of one backup schedule.

Parameters:

schedule_id (str) – ID of the schedule to describe, from create() or list(). Not the index name.

Returns:

A BackupScheduleModel carrying the schedule’s frequency, its enabled flag, its retention_expire_after_days window, and next_scheduled_run, which is None while the schedule is disabled.

Raises:
Return type:

BackupScheduleModel

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> schedule = pc.backup_schedules.describe(
...     schedule_id="e88f7273-42aa-47e9-af73-593827136867"
... )
>>> print(schedule.enabled, schedule.next_scheduled_run)
True 2026-04-03 06:00:00+00:00
get(*, schedule_id)[source]

Get the current configuration of one backup schedule (alias for describe()).

Parameters:

schedule_id (str) – ID of the schedule to describe, from create() or list(). Not the index name.

Returns:

A BackupScheduleModel carrying the schedule’s frequency, its enabled flag, its retention_expire_after_days window, and next_scheduled_run, which is None while the schedule is disabled.

Raises:
Return type:

BackupScheduleModel

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> schedule = pc.backup_schedules.get(
...     schedule_id="e88f7273-42aa-47e9-af73-593827136867"
... )
>>> schedule.frequency
'daily'
update(*, schedule_id, frequency=None, retention_days=None, enabled=None)[source]

Update a backup schedule’s cadence, retention, or enabled state.

Only the arguments you pass change; the rest keep their current values. A schedule’s name and index cannot be changed.

Parameters:
  • schedule_id (str) – ID of the schedule to update.

  • frequency (str | None) – New cadence: "daily", "weekly", or "monthly". None leaves it unchanged.

  • retention_days (int | None) – New retention window in days, at least 1. Also applies to unexpired backups this schedule already produced. None leaves it unchanged.

  • enabled (bool | None) – False pauses the schedule and clears next_scheduled_run; True resumes a paused one (see the warning below). None leaves it unchanged.

Returns:

A BackupScheduleModel with the updated configuration. After enabled=False its next_scheduled_run is None.

Raises:
  • PineconeValueError – If schedule_id is empty, if frequency is set to an unsupported cadence, or if retention_days is set to less than 1.

  • PineconeTypeError – If schedule_id is not a str.

  • ForbiddenError – If the project’s plan does not include scheduled backups.

  • NotFoundError – If the schedule does not exist.

  • ConflictError – If enabled=True and another schedule on the same index is already enabled.

Return type:

BackupScheduleModel

Examples

Move a schedule to a weekly cadence with a shorter retention window. Its name and enabled state stay as they were:

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> updated = pc.backup_schedules.update(
...     schedule_id="e88f7273-42aa-47e9-af73-593827136867",
...     frequency="weekly",
...     retention_days=30,
... )
>>> print(updated.frequency, updated.retention_expire_after_days)
weekly 30
>>> print(updated.name, updated.enabled)
compliance-snapshots True

Pause the schedule, keeping the rest of its configuration:

>>> paused = pc.backup_schedules.update(
...     schedule_id="e88f7273-42aa-47e9-af73-593827136867",
...     enabled=False,
... )
>>> print(paused.frequency, paused.next_scheduled_run)
daily None

Warning

Re-enabling a paused schedule plans its next run from the time of the update, not from its old slot, so a pause shifts the cadence. Re-enabling raises ConflictError if another schedule on the same index is already enabled.

delete(*, schedule_id)[source]

Delete a backup schedule.

Deleting a schedule stops its future runs. Backups it already produced are not deleted.

Parameters:

schedule_id (str) – ID of the schedule to delete.

Raises:
Return type:

None

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> pc.backup_schedules.delete(
...     schedule_id="e88f7273-42aa-47e9-af73-593827136867"
... )

Important

If a delete’s response is lost and the call is retried, the retry raises NotFoundError because the first attempt already deleted the schedule. Treat NotFoundError from a delete as success.

history(*, schedule_id, limit=None, pagination_token=None)[source]

List one page of the backups a schedule has produced.

Each row is a backup. The schedule’s next run is listed as soon as it is planned, before it starts, so check each row’s status. To walk every page, use iter_history(); see Pagination.

Parameters:
  • schedule_id (str) – ID of the schedule whose history to list.

  • limit (int | None) – Maximum results per page, for example 20. None uses the server’s page size. Ignored when pagination_token is set, because the token carries its own page size.

  • pagination_token (str | None) – The pagination.next value from the previous page, or None for the first page.

Returns:

A BackupScheduleHistoryList of BackupScheduleHistoryItem that supports iteration, len(), and index access. Its pagination is None on the last page.

Raises:
Return type:

BackupScheduleHistoryList

Examples

Walk the history a page at a time and print the finished backups:

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> pagination_token = None
>>> while True:
...     runs = pc.backup_schedules.history(
...         schedule_id="e88f7273-42aa-47e9-af73-593827136867",
...         pagination_token=pagination_token,
...     )
...     for run in runs:
...         if run.status == "Ready":
...             print(run.name, run.size_bytes)
...     pagination_token = runs.pagination.next if runs.pagination else None
...     if pagination_token is None:
...         break
compliance-snapshots-20260401T060000Z 4194304
iter_history(*, schedule_id, limit=None, pagination_token=None)[source]

Iterate every backup a schedule has produced, fetching pages on demand.

The auto-paginating twin of history().

Parameters:
  • schedule_id (str) – ID of the schedule whose history to iterate.

  • limit (int | None) – Maximum number of backups to yield across all pages. Must be positive. None yields all of them.

  • pagination_token (str | None) – Token to resume from a previous call. limit still caps the total yield.

Returns:

A Paginator over BackupScheduleHistoryItem instances.

Raises:
  • PineconeValueError – If schedule_id is empty or limit is zero or negative. Raised as soon as you call this method, before the first page is fetched.

  • PineconeTypeError – If schedule_id is not a str.

  • ForbiddenError – If the project’s plan does not include scheduled backups. Raised while iterating, when a page is fetched.

  • NotFoundError – If the schedule does not exist.

Return type:

Paginator[BackupScheduleHistoryItem]

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> for run in pc.backup_schedules.iter_history(
...     schedule_id="e88f7273-42aa-47e9-af73-593827136867"
... ):
...     if run.status == "Ready":
...         print(run.name, run.size_bytes)
compliance-snapshots-20260401T060000Z 4194304

RestoreJobs

class pinecone.client.restore_jobs.RestoreJobs(http)[source]

Bases: object

Progress reports for restores of a backup into a new index.

create_index_from_backup() hands back a restore_job_id and leaves the restore running in the background; use this namespace to follow it to completion. Reached as pc.restore_jobs; not constructed directly.

A restore job is not a backup: Backups manages the snapshots themselves, while a job here is a read-only record of one attempt at turning a snapshot back into an index.

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> job = pc.restore_jobs.describe(job_id="rj-abc123")
>>> job.status, job.target_index_name
('Completed', 'product-search-restored')

See also

Error handling, for the exceptions these methods raise and which ones to retry.

Parameters:

http (HTTPClient)

__init__(http)[source]
Parameters:

http (HTTPClient)

Return type:

None

list(*, limit=None, pagination_token=None)[source]

List one page of the project’s restore jobs.

One call returns one page, and iterating the result does not fetch the next one. Follow pagination.next yourself (see Pagination). The listing is not exhaustive; see the warning below.

Parameters:
  • limit (int | None) – Maximum number of results per page, e.g. 100. When None, the server applies its default. The SDK drops limit when pagination_token is given, because the token already carries the page size.

  • pagination_token (str | None) – Token for the next page, taken from RestoreJobList.pagination.next.

Returns:

A RestoreJobList holding one page, supporting iteration, len(), and index access. pagination is None on the final page.

Return type:

RestoreJobList

Examples

Walk every page, keying jobs by restore_job_id because pages can overlap:

from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")

by_id = {}
page = pc.restore_jobs.list(limit=100)
while True:
    for job in page:
        by_id[job.restore_job_id] = job
    if not (page.pagination and page.pagination.next):
        break
    page = pc.restore_jobs.list(pagination_token=page.pagination.next)

for job in by_id.values():
    print(job.restore_job_id, job.target_index_name, job.status)

When one page is all you want:

page = pc.restore_jobs.list(limit=5)
print(len(page))

Warning

The restore-job listing is not exhaustive. Pages can overlap, pagination can end while jobs remain, and jobs whose target index has been deleted are left out. De-duplicate by restore_job_id, and never conclude a job does not exist because the listing omits it. To track a specific restore, keep its restore_job_id and call describe().

describe(*, job_id)[source]

Get the current state of one restore job.

Parameters:

job_id (str) – The identifier of the restore job to describe.

Returns:

A RestoreJobModel naming the backup_id restored and the target_index_name it lands in. status is one of "Pending", "Completed", "Failed", or "Cancelled"; a restore that is running reports "Pending". percent_complete and completed_at are set only once status is "Completed", so percent_complete cannot report progress.

Raises:
Return type:

RestoreJobModel

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> job = pc.restore_jobs.describe(job_id="rj-abc123")
>>> job.status
'Completed'
>>> job.target_index_name
'product-search-restored'

To wait for a restore, poll until status leaves "Pending". A deadline keeps a stuck job from looping forever:

import time

deadline = time.monotonic() + 600
job = pc.restore_jobs.describe(job_id="rj-abc123")
while job.status == "Pending" and time.monotonic() < deadline:
    time.sleep(5)
    job = pc.restore_jobs.describe(job_id="rj-abc123")

print(job.status, job.completed_at)

Warning

A NotFoundError here does not prove the job does not exist. The server also answers 404 on a transient failure and for a job whose target index has been deleted. Treat a 404 as possibly transient unless you know the ID is wrong.

Inference

class pinecone.client.inference.Inference(config)[source]

Bases: object

Embedding and reranking against Pinecone’s hosted models.

Reached as pc.inference. Call these when you want the vectors or the scores in your own hands: to store somewhere else, to embed a query yourself, or to rerank candidates that came from another system. If instead you want Pinecone to embed on your behalf, give a document index a string field with integrated embedding (embed / sparse_embed), which needs no explicit embed step. Legacy integrated indexes, created via create_for_model(), do the same through the legacy Records API (upsert_records()). Not constructed directly.

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> embeddings = pc.inference.embed(
...     model="multilingual-e5-large",
...     inputs=["Vector databases index embeddings for similarity search."],
...     parameters={"input_type": "passage"},
... )
>>> len(embeddings)
1

See also

Error handling covers the exceptions every method here can raise, and how to retry them.

Parameters:

config (PineconeConfig)

class EmbedModel(value)

Bases: str, Enum

Known embedding models, for integrated embedding and pc.inference.

A convenience enum rather than an exhaustive list: model is also accepted as a plain string, so a model added after this SDK release can still be used. Call list_models() for the models currently available.

Multilingual_E5_Large = 'multilingual-e5-large'
Pinecone_Sparse_English_V0 = 'pinecone-sparse-english-v0'
Llama_Text_Embed_V2 = 'llama-text-embed-v2'
Pinecone_Sparse_Multilingual_V0 = 'pinecone-sparse-multilingual-v0'
class RerankModel(value)

Bases: str, Enum

Known reranking models.

Like EmbedModel, a convenience enum rather than an exhaustive list.

Note

Pinecone_Rerank_V0 is deprecated and most projects can no longer use it: a request naming it is rejected with a permission error whose message points to a current model. Prefer another member of this enum.

Bge_Reranker_V2_M3 = 'bge-reranker-v2-m3'
Cohere_Rerank_3_5 = 'cohere-rerank-3.5'
Pinecone_Rerank_V0 = 'pinecone-rerank-v0'
__init__(config)[source]
Parameters:

config (PineconeConfig)

Return type:

None

close()[source]

Close the underlying HTTP client.

Return type:

None

property model: ModelResource

Model discovery for this namespace.

Returns:

A ModelResource exposing list() and get().

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> info = pc.inference.model.get("multilingual-e5-large")
>>> info.default_dimension
1024
>>> pc.inference.model.list().names()
['multilingual-e5-large', 'pinecone-sparse-english-v0', 'bge-reranker-v2-m3']
embed(model, inputs, parameters=None)[source]

Generate embeddings for the provided inputs.

Many models are asymmetric: they embed a stored passage and a search query differently. Where a model accepts input_type, pass it in parameters, or the query and the corpus will not line up.

Parameters:
  • model (EmbedModel | str) – Embedding model name, e.g. "multilingual-e5-large". An EmbedModel member is accepted too; call list_models() with type="embed" for the names currently available.

  • inputs (str | Sequence[str] | Sequence[Mapping[str, Any]]) – The text to embed. Any sequence (list, tuple) of strings or mappings; a bare string is wrapped for you and still comes back as a one-item result rather than a lone embedding.

  • parameters (Mapping[str, Any] | None) – Model-specific parameters (e.g., {"input_type": "passage", "truncate": "END"}). Call get_model() and read supported_parameters to discover the keys a given model accepts.

Returns:

EmbeddingsList with one embedding per input, in input order. Iterating it (or indexing into it) yields the embeddings themselves, and data holds the same list. vector_type says which shape they are and so which fields they carry: DenseEmbedding has values, while SparseEmbedding has sparse_values and sparse_indices. model names the model that served the request, and usage.total_tokens the tokens counted for it.

Raises:
  • PineconeValueError – If model is empty or inputs is empty.

  • PineconeTypeError – If inputs has an invalid type.

  • NotFoundError – If model is not available to this project: either no such model exists, or the project is not authorized to use it. The error does not distinguish the two cases.

Return type:

EmbeddingsList

Examples

Embed the text you intend to store. input_type="passage" is the corpus side of a search:

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> embeddings = pc.inference.embed(
...     model="multilingual-e5-large",
...     inputs=[
...         "Vector databases index embeddings for similarity search.",
...         "Reranking reorders candidate results by relevance.",
...     ],
...     parameters={"input_type": "passage"},
... )
>>> len(embeddings)
2
>>> embeddings.vector_type
'dense'

Embed the search query with input_type="query". The two are not interchangeable: a query embedded as a passage will not land where the model expects it:

>>> query = pc.inference.embed(
...     model="multilingual-e5-large",
...     inputs="How does reranking work?",
...     parameters={"input_type": "query"},
... )
>>> len(query.data)
1

Note

To store these vectors, upsert each embedding’s values into a dense_vector field of a document index (here embedding) through documents:

index = pc.index("product-search")
index.documents.upsert(
    namespace="products-en",
    documents=[{"_id": "prod-1", "embedding": embeddings.data[0].values}],
)

values exists only on the dense shape. A sparse embedding model returns SparseEmbedding objects, which carry sparse_values and sparse_indices and have no values field. Reading .values on one hands back a dict-view method rather than a vector, and raises nothing to warn you. Branch on embeddings.vector_type when the model is not fixed in advance.

See also

Embeddings covers storing and searching these vectors. On a document index whose string field uses integrated embedding, Pinecone embeds the text for you and no call here is needed.

rerank(model, query, documents, rank_fields=['text'], return_documents=True, top_n=None, parameters=None)[source]

Rerank documents by relevance to a query.

Parameters:
  • model (RerankModel | str) – Reranking model name, e.g. "bge-reranker-v2-m3". A RerankModel member is accepted too; call list_models() with type="rerank" for the names currently available.

  • query (str) – The text the documents are scored against.

  • documents (Sequence[str] | Sequence[Mapping[str, Any]]) – Documents to rank. Any sequence (list, tuple) of strings or mappings. A bare string is wrapped as {"text": ...}, which is what the default rank_fields scores on.

  • rank_fields (Sequence[str]) – The document keys to score, e.g. ["summary"] when the text lives under summary. Defaults to ["text"].

  • return_documents (bool) – Send each document back in its result. Leave it True to read .document; set it False when you already hold the documents and want only index and score.

  • top_n (int | None) – Keep only the n best-scoring documents. None, the default, returns a result for every document.

  • parameters (Mapping[str, Any] | None) – Model-specific parameters. Call get_model() and read supported_parameters to discover the keys a given model accepts.

Returns:

RerankResult whose data is a list of RankedDocument ordered by descending score. Each one carries the index it held in documents and, unless return_documents is False, the document itself. model names the model that served the request, and usage.rerank_units the units counted for it.

Raises:
  • PineconeValueError – If model, query, or documents is empty, or top_n is less than 1.

  • PineconeTypeError – If documents has an invalid type.

  • NotFoundError – If model does not name a model the API serves. A typo in the model name surfaces here, so check this before assuming the request body was at fault.

  • ForbiddenError – If the project is not authorized to use model, including when model has been deprecated.

Return type:

RerankResult

Examples

Rank a list of strings against the query:

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> result = pc.inference.rerank(
...     model="bge-reranker-v2-m3",
...     query="Tell me about tech companies",
...     documents=["Apple is a fruit.", "Acme Inc. revolutionized tech."],
...     top_n=1,
... )

result.data is ordered by descending relevance, not by the order the documents were passed in. Read .index to map a result back to its position in documents. The top hit here is the second document, so its .index is 1, not 0:

>>> top = result.data[0]
>>> top.index, top.score
(1, 0.95)
>>> top.document["text"]
'Acme Inc. revolutionized tech.'

Pass mappings instead when you want your own identifiers back alongside the scores. Every key other than the ones named in rank_fields rides along untouched and comes back in .document:

>>> result = pc.inference.rerank(
...     model="bge-reranker-v2-m3",
...     query="Tell me about tech companies",
...     documents=[
...         {"id": "doc-1", "summary": "Apple is a fruit."},
...         {"id": "doc-2", "summary": "Acme Inc. revolutionized tech."},
...     ],
...     rank_fields=["summary"],
...     top_n=1,
... )
>>> result.data[0].document["id"]
'doc-2'

Note

The model you request may not be the model that serves the request; Pinecone may substitute a different one. result.model reports which one did, so read it there rather than assuming it echoes model.

See also

search() on a legacy integrated index takes a rerank argument that reranks that search’s own hits in one round trip. Reach for the method here when the candidates came from somewhere else.

list_models(*, type=None, vector_type=None)[source]

List the inference models available to this project.

Parameters:
  • type (str | None) – Restrict the listing to one model type, "embed" or "rerank". Omit it to get both.

  • vector_type (str | None) – Restrict embedding models to those producing "dense" or "sparse" vectors. Carries meaning only alongside type="embed".

Returns:

ModelInfoList, a sequence of ModelInfo supporting iteration, indexing and len(), plus names() when you want the model identifiers alone.

Raises:

PineconeValueError – If type or vector_type is not one of the values above, or if vector_type is paired with type="rerank". The client rejects that pairing rather than ignoring it.

Return type:

ModelInfoList

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> models = pc.inference.list_models()
>>> models.names()
['multilingual-e5-large', 'pinecone-sparse-english-v0', 'bge-reranker-v2-m3']

Narrow to the embedding models that produce sparse vectors:

>>> sparse = pc.inference.list_models(type="embed", vector_type="sparse")
>>> sparse.names()
['pinecone-sparse-english-v0']
get_model(*, model=None, **kwargs)[source]

Describe one inference model.

Parameters:
  • model (str) – The model name to look up, e.g. "multilingual-e5-large". Call list_models() for the names currently available.

  • model_name (str) – Deprecated alias for model. Passing both raises PineconeValueError.

  • kwargs (str)

Returns:

ModelInfo with supported_parameters (the keys parameters accepts on embed() and rerank() for this model), type, and, for embedding models, vector_type, default_dimension and supported_dimensions.

Raises:
Return type:

ModelInfo

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> model_info = pc.inference.get_model(model="multilingual-e5-large")
>>> model_info.type
'embed'

supported_parameters is what embed() and rerank() point at for discovering the keys their parameters argument accepts, and each entry names the values it will take:

>>> for p in model_info.supported_parameters:
...     print(p.parameter, p.allowed_values)
input_type ['query', 'passage']
truncate ['END', 'NONE', 'START']
dimension [1024]
class pinecone.client.inference.ModelResource(inference)[source]

Bases: object

Discovery for the embedding and reranking models a project can use.

Reached as pc.inference.model. Its two methods are the same operations as Inference.list_models() and Inference.get_model(); take whichever reads better at the call site. Not constructed directly.

Examples

An unfiltered listing spans both embedding and reranking models:

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> models = pc.inference.model.list()
>>> models.names()
['multilingual-e5-large', 'pinecone-sparse-english-v0', 'bge-reranker-v2-m3']
Parameters:

inference (Inference)

__init__(inference)[source]
Parameters:

inference (Inference)

Return type:

None

list(*, type=None, vector_type=None)[source]

List the inference models available to this project.

Delegates to Inference.list_models().

Parameters:
  • type (str | None) – Restrict the listing to one model type, "embed" or "rerank". Omit it to get both.

  • vector_type (str | None) – Restrict embedding models to those producing "dense" or "sparse" vectors. Carries meaning only alongside type="embed".

Returns:

ModelInfoList, a sequence of ModelInfo supporting iteration, indexing and len(), plus names() when you want the model identifiers alone.

Raises:

PineconeValueError – If type or vector_type is not one of the values above, or if vector_type is paired with type="rerank". The client rejects that pairing rather than ignoring it.

Return type:

ModelInfoList

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> for info in pc.inference.model.list():
...     print(info.model, info.type)
multilingual-e5-large embed
pinecone-sparse-english-v0 embed
bge-reranker-v2-m3 rerank

Narrow to the embedding models that produce sparse vectors:

>>> sparse = pc.inference.model.list(type="embed", vector_type="sparse")
>>> sparse.names()
['pinecone-sparse-english-v0']
get(model=None, **kwargs)[source]

Describe one inference model.

Delegates to Inference.get_model().

Parameters:
  • model (str) – The model name to look up, e.g. "multilingual-e5-large". Call list() for the names currently available.

  • model_name (str) – Deprecated alias for model. Passing both raises PineconeValueError.

  • kwargs (str)

Returns:

ModelInfo with supported_parameters (the keys this model accepts in a parameters argument), type, and, for embedding models, vector_type, default_dimension and supported_dimensions.

Raises:
Return type:

ModelInfo

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> info = pc.inference.model.get("multilingual-e5-large")
>>> info.type
'embed'

Assistants

class pinecone.client.assistants.Assistants(config)[source]

Bases: AssistantsLegacyNamespaceMixin

Control-plane operations for Pinecone assistants.

A Pinecone assistant is a managed question-answering service grounded in documents you upload to it: create the assistant, upload files, then chat against them and get answers with citations back to the files that supported each claim.

Reached as pc.assistants; not constructed directly. Unlike an index, which you query for records you then feed to your own model, an assistant does the retrieval and the generation for you.

Examples

from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")
for assistant in pc.assistants.list():
    print(assistant.name, assistant.status)

See also

Error handling: the exceptions any of these methods can raise, and which ones are worth retrying.

Parameters:

config (PineconeConfig)

__init__(config)[source]
Parameters:

config (PineconeConfig)

Return type:

None

close()[source]

Release the HTTP connections held by this namespace.

Call this when you’re done using pc.assistants to free pooled connections, including any opened for individual assistants.

Return type:

None

upload_file(*, assistant_name, file_path=None, file_stream=None, file_name=None, metadata=None, multimodal=None, file_id=None, timeout=None)[source]

Upload a file to a Pinecone assistant.

Uploads a file from a local path or an in-memory byte stream, then waits until processing finishes before returning. The server decides how to process the file from its extension, which must be .txt, .pdf, .json, .md or .docx.

Parameters:
  • assistant_name (str) – Name of the target assistant.

  • file_path (str | None) – Path to a local file to upload. Mutually exclusive with file_stream.

  • file_stream (IO[bytes] | None) – An open byte stream to upload. Mutually exclusive with file_path. Requires file_name.

  • file_name (str | None) – Filename for file_stream, including its extension, e.g. "q3-revenue-review.pdf". Required with file_stream. Ignored with file_path, whose basename is used instead.

  • metadata (dict[str, Any] | None) – Metadata to attach to the file, e.g. {"department": "finance"}. The filter argument of list_files(), chat() and context() matches against it.

  • multimodal (bool | None) – Whether to enable multimodal processing for PDFs.

  • file_id (str | None) – Optional identifier for the uploaded file. When given, any existing file with that id is replaced. Otherwise the server assigns one.

  • timeout (float | None) – Seconds to wait for processing to complete. None (default) polls indefinitely. Use -1 to return as soon as the server accepts the upload, while the file may still be "Processing". Raises PineconeTimeoutError if processing is not done before the deadline.

Returns:

AssistantFileModel describing the uploaded file, once processing completes.

Raises:
  • PineconeTypeError – If assistant_name is not a str, or file_id is given and is not a str.

  • PineconeValueError – If both or neither of file_path and file_stream are provided, if file_path does not exist, or if file_stream is used without a file_name carrying a file extension.

  • PineconeTimeoutError – If processing does not complete before timeout.

  • PineconeError – If processing fails.

Return type:

AssistantFileModel

Examples

Upload from a local path. The basename supplies the extension the server types the file by:

file = pc.assistants.upload_file(
    assistant_name="research-assistant",
    file_path="/data/q3-revenue-review.pdf",
)
print(file.status)

Or upload from an open byte stream instead. Pass exactly one of file_path and file_stream; a stream needs file_name to carry the extension a path would have supplied:

>>> import io
>>> file = pc.assistants.upload_file(
...     assistant_name="research-assistant",
...     file_stream=io.BytesIO(b"%PDF-1.4 Q3 revenue review"),
...     file_name="q3-revenue-review.pdf",
...     metadata={"department": "finance", "quarter": "2024-Q3"},
... )
>>> file.status
'Available'
describe_file(*, assistant_name, file_id, include_url=False)[source]

Get the status and metadata of a file uploaded to an assistant.

Parameters:
  • assistant_name (str) – Name of the assistant that owns the file.

  • file_id (str) – Unique identifier of the file to retrieve.

  • include_url (bool) – If True, include a signed download URL in the response. Defaults to False.

Returns:

AssistantFileModel with id, name, status, metadata, size, multimodal, created_on, updated_on and content_hash, plus signed_url when include_url is True.

Raises:
Return type:

AssistantFileModel

Examples

>>> file = pc.assistants.describe_file(
...     assistant_name="research-assistant",
...     file_id="file-abc123",
... )
>>> file.status
'Available'

See also

list_files(): every file on the assistant. That listing drops a "ProcessingFailed" file once it is old enough; this method still returns it by id.

list_files(*, assistant_name, filter=None, limit=None, pagination_token=None)[source]

List files for an assistant with lazy pagination.

A "ProcessingFailed" file drops out of this listing once its created_on passes the listing’s age cutoff. It is not deleted: describe_file() still returns it by id.

Parameters:
  • assistant_name (str) – Name of the assistant whose files to list.

  • filter (dict[str, Any] | None) – Metadata filter, e.g. {"department": "finance"}. Only files whose metadata matches are listed.

  • limit (int | None) – Maximum number of files to yield across all pages. None (default) yields all files.

  • pagination_token (str | None) – Token to resume pagination from a previous call.

Returns:

Paginator over AssistantFileModel objects. Supports for loops, .to_list(), .pages(), and limit.

Raises:
Return type:

Paginator[AssistantFileModel]

Examples

for f in pc.assistants.list_files(assistant_name="research-assistant"):
    print(f.name, f.status)

The paginator fetches pages lazily as you iterate. Call to_list() instead when you want every file materialized up front:

files = pc.assistants.list_files(assistant_name="research-assistant").to_list()

See also

  • describe_file(): one file by id, with no age filter.

  • list_files_page(): one page at a time, when you want to hold the continuation token yourself.

  • Pagination: how the paginator and the continuation tokens work.

list_files_page(*, assistant_name, page_size=None, pagination_token=None, filter=None, **kwargs)[source]

List one page of files for an assistant with explicit pagination control.

Parameters:
  • assistant_name (str) – Name of the assistant whose files to list.

  • page_size (int | None) – Maximum number of files in this page. Omit it to let the server choose the page size.

  • pagination_token (str | None) – Token from a previous response to fetch the next page.

  • filter (dict[str, Any] | None) – Metadata filter, e.g. {"department": "finance"}. Only files whose metadata matches are listed.

  • **kwargs (Any) – Accepts the legacy alias limit for page_size. Passing both, or any other keyword, raises PineconeValueError.

Returns:

ListFilesResponse with a files list and an optional next continuation token.

Raises:
Return type:

ListFilesResponse

Examples

page = pc.assistants.list_files_page(
    assistant_name="research-assistant",
    page_size=10,
)
for f in page.files:
    print(f.name)
if page.next:
    next_page = pc.assistants.list_files_page(
        assistant_name="research-assistant",
        page_size=10,
        pagination_token=page.next,
    )

See also

Pagination: the continuation-token loop this method expects you to drive, and the paginator that drives it for you.

delete_file(*, assistant_name, file_id, timeout=None)[source]

Delete a file from a Pinecone assistant.

Deletion can finish immediately or run as a pending operation, depending on the file’s state. When it is pending, this method polls until it finishes, unless you pass timeout=-1.

Parameters:
  • assistant_name (str) – Name of the assistant that owns the file.

  • file_id (str) – Unique identifier of the file to delete.

  • timeout (float | None) – Seconds to wait for the deletion to finish. Use None (default) to poll indefinitely. Use -1 to return as soon as the request is accepted; the file may still exist when this returns. Use a positive value to poll with a deadline. Raises PineconeTimeoutError if the deletion is not done before the deadline.

Returns:

None

Raises:
  • PineconeTypeError – If assistant_name or file_id is not a str.

  • NotFoundError – If file_id does not name a file on this assistant, including a file that has already been deleted.

  • PineconeError – If the deletion operation reports failure.

  • PineconeTimeoutError – If the deletion has not finished after timeout seconds.

Return type:

None

Examples

>>> pc.assistants.delete_file(
...     assistant_name="research-assistant",
...     file_id="file-abc123",
... )
describe_operation(*, assistant_name, operation_id)[source]

Get the current status of a long-running assistant operation.

upload_file() and delete_file() poll their own operation for you by default. Reach for this method when you called one of them with timeout=-1 and want to check on it later, for example to find the file a fire-and-forget upload created, via OperationModel.file_id.

Parameters:
Returns:

OperationModel with status, operation_type, file_id, percent_complete, created_at, completed_on, ingestion_units and error. status is "Processing", "Completed" or "Failed". Check status, not error, to tell whether the operation failed.

Raises:
  • PineconeTypeError – If assistant_name or operation_id is not a str.

  • NotFoundError – If the assistant or the operation does not exist. The server keeps finished operations for a limited time, so an old operation id also raises this.

Return type:

OperationModel

Examples

>>> operation = pc.assistants.describe_operation(
...     assistant_name="research-assistant",
...     operation_id="op-1234-abcd-5678",
... )
>>> operation.status, operation.percent_complete
('Completed', 100)

See also

list_operations(): every operation on the assistant, when you did not keep the operation id.

list_operations(*, assistant_name, operation_type=None, status=None, limit=None, pagination_token=None)[source]

List an assistant’s operations with lazy pagination.

Includes operations still in progress and finished ones, successful or failed. The server keeps finished operations for a limited time.

Parameters:
  • assistant_name (str) – Name of the assistant whose operations to list.

  • operation_type (str | None) – Restrict the listing to one kind of operation. One of "upload_file", "upsert_file", "update_file_metadata" or "delete_file".

  • status (str | None) – Restrict the listing to one status. One of "Processing", "Completed" or "Failed" (case-sensitive).

  • limit (int | None) – Maximum number of operations to yield across all pages. None (default) yields all of them.

  • pagination_token (str | None) – Token to resume pagination from a previous call.

Returns:

Paginator over OperationModel objects. Supports for loops, .to_list(), .pages(), and limit.

Raises:
Return type:

Paginator[OperationModel]

Examples

for op in pc.assistants.list_operations(assistant_name="research-assistant"):
    print(op.operation_id, op.status, op.percent_complete)

Filter server-side to narrow the listing, here to uploads that have not finished yet:

pending = pc.assistants.list_operations(
    assistant_name="research-assistant",
    operation_type="upload_file",
    status="Processing",
).to_list()

See also

list_operations_page(*, assistant_name, operation_type=None, status=None, page_size=None, pagination_token=None)[source]

List one page of an assistant’s operations with explicit pagination control.

Parameters:
  • assistant_name (str) – Name of the assistant whose operations to list.

  • operation_type (str | None) – Restrict the listing to one kind of operation. One of "upload_file", "upsert_file", "update_file_metadata" or "delete_file".

  • status (str | None) – Restrict the listing to one status. One of "Processing", "Completed" or "Failed" (case-sensitive).

  • page_size (int | None) – Maximum number of operations in this page. Omit it to let the server choose the page size.

  • pagination_token (str | None) – Token from a previous response to fetch the next page.

Returns:

ListOperationsResponse with an operations list and an optional next continuation token.

Raises:
Return type:

ListOperationsResponse

Examples

page = pc.assistants.list_operations_page(
    assistant_name="research-assistant",
    status="Failed",
    page_size=10,
)
for op in page.operations:
    print(op.operation_id, op.error)
if page.next:
    next_page = pc.assistants.list_operations_page(
        assistant_name="research-assistant",
        status="Failed",
        page_size=10,
        pagination_token=page.next,
    )

See also

Pagination: the continuation-token loop this method expects you to drive, and the paginator that drives it for you.

create(*, name=None, instructions=None, metadata=None, region='us', environment=None, timeout=None, **kwargs)[source]

Create a new Pinecone assistant.

By default, blocks until the assistant reaches "Ready" status, so you can upload files to it as soon as the call returns.

Parameters:
  • name (str) – Name for the new assistant, e.g. "docs-assistant". Must be unique within the project. The server validates the name and rejects an invalid one.

  • instructions (str | None) – Guidance the assistant applies to every response, e.g. "Always cite the source document.".

  • metadata (dict[str, Any] | None) – Optional metadata to attach to the assistant, e.g. {"team": "docs"}.

  • region (str) – Region to deploy the assistant in, "us" or "eu". Defaults to "us". Cannot be changed afterwards: an assistant in the wrong region has to be recreated.

  • environment (str | None) – Reserved for internal Pinecone use. Leave it unset; the server rejects it for other projects.

  • timeout (float | None) – Seconds to wait for the assistant to become ready. Use None (default) to poll indefinitely, -1 to return immediately without polling, or a non-negative value to poll with a deadline.

  • **kwargs (Any) – Accepts the legacy alias assistant_name for name. Passing both, or any other keyword, raises PineconeValueError.

Returns:

AssistantModel describing the created assistant.

Raises:
  • PineconeTypeError – If name is not a str.

  • PineconeValueError – If region is not "us" or "eu".

  • PineconeError – If the assistant fails to initialize or is deleted while the call waits for it.

  • PineconeTimeoutError – If the assistant does not become ready before the deadline.

  • ConflictError – If an assistant of this name already exists in the project.

  • RateLimitError – If the project has reached its assistant limit. Retrying does not help; delete an assistant you no longer need first.

Return type:

AssistantModel

Examples

>>> from pinecone import Pinecone
>>> pc = Pinecone(api_key="your-api-key")
>>> assistant = pc.assistants.create(name="research-assistant")
>>> assistant.status
'Ready'

Instructions, metadata and region are all optional. create returns once the assistant reaches "Ready", so the assistant below is usable as soon as the call returns:

>>> assistant = pc.assistants.create(
...     name="support-docs-assistant",
...     instructions="Always cite the source document.",
...     metadata={"team": "support", "cost_center": "R-4120"},
...     region="eu",
... )
>>> assistant.status
'Ready'
describe(*, name=None, **kwargs)[source]

Get detailed information about a named assistant.

Parameters:
  • name (str) – The name of the assistant to describe.

  • **kwargs (Any) – Accepts the legacy alias assistant_name for name. Passing both, or any other keyword, raises PineconeValueError.

Returns:

AssistantModel with name, status, region, host, instructions, metadata, created_at and updated_at.

Raises:
Return type:

AssistantModel

Examples

>>> assistant = pc.assistants.describe(name="research-assistant")
>>> assistant.status
'Ready'
list(*, limit=None, pagination_token=None)[source]

List assistants in the project with lazy pagination.

Parameters:
  • limit (int | None) – Maximum number of assistants to yield across all pages. None (default) yields all assistants.

  • pagination_token (str | None) – Token to resume pagination from a previous call.

Returns:

Paginator over AssistantModel objects. Supports for loops, .to_list(), .pages(), and limit.

Return type:

Paginator[AssistantModel]

Examples

for assistant in pc.assistants.list():
    print(assistant.name, assistant.status)

The paginator fetches pages lazily as you iterate. Call to_list() instead when you want every assistant materialized up front:

all_assistants = pc.assistants.list().to_list()

See also

  • list_page(): one page at a time, when you want to hold the continuation token yourself.

  • Pagination: how the paginator and the continuation tokens work.

list_page(*, page_size=None, pagination_token=None, **kwargs)[source]

List one page of assistants with explicit pagination control.

Parameters:
  • page_size (int | None) – Maximum number of assistants per page. Omit it to let the server choose the page size.

  • pagination_token (str | None) – Token from a previous response to fetch the next page.

  • **kwargs (Any) – Accepts the legacy alias limit for page_size. Passing both, or any other keyword, raises PineconeValueError.

Returns:

ListAssistantsResponse with an assistants list and an optional next continuation token.

Return type:

ListAssistantsResponse

Examples

page = pc.assistants.list_page(page_size=10)
for assistant in page.assistants:
    print(assistant.name)
if page.next:
    next_page = pc.assistants.list_page(
        page_size=10,
        pagination_token=page.next,
    )

See also

Pagination: the continuation-token loop this method expects you to drive, and the paginator that drives it for you.

update(*, name=None, instructions=None, metadata=None, **kwargs)[source]

Update an existing Pinecone assistant.

Pass at least one of instructions and metadata. A field left as None keeps its current value; to clear a field, pass its empty value (instructions="" or metadata={}).

Parameters:
  • name (str) – The name of the assistant to update.

  • instructions (str | None) – New instructions for the assistant. Pass an empty string to clear existing instructions.

  • metadata (dict[str, Any] | None) – New metadata dictionary. Fully replaces any existing metadata rather than merging. Pass an empty dict to clear existing metadata.

  • **kwargs (Any) – Accepts the legacy alias assistant_name for name. Passing both, or any other keyword, raises PineconeValueError.

Returns:

AssistantModel describing the updated assistant.

Raises:
Return type:

AssistantModel

Examples

Patch only the instructions. metadata is left out of the request body entirely, so whatever metadata the assistant already carries survives untouched:

>>> assistant = pc.assistants.update(
...     name="research-assistant",
...     instructions="Always cite the source document.",
... )

Passing metadata replaces the whole dictionary instead of merging into it. An assistant carrying {"team": "research", "cost_center": "R-4120"} is left with only team after the call below. Its instructions stay unchanged, since they were not named:

>>> assistant = pc.assistants.update(
...     name="research-assistant",
...     metadata={"team": "docs-platform"},
... )
delete(*, name=None, timeout=None, **kwargs)[source]

Delete a Pinecone assistant by name.

Deleting an assistant also deletes its files. By default, blocks until the assistant is confirmed gone.

Parameters:
  • name (str) – The name of the assistant to delete.

  • timeout (float | None) – Seconds to wait for the assistant to disappear. Use None (default) to poll indefinitely. Use -1 to return immediately without polling. Use a positive value to poll with a deadline. Raises PineconeTimeoutError if the assistant is not gone before the deadline.

  • **kwargs (Any) – Accepts the legacy alias assistant_name for name. Passing both, or any other keyword, raises PineconeValueError.

Returns:

None

Raises:
Return type:

None

Examples

pc.assistants.delete(name="research-assistant")

The call above blocks until the assistant is confirmed gone. Pass timeout=-1 to return as soon as the request is accepted; the assistant may still be terminating when this returns:

pc.assistants.delete(name="stale-prototype", timeout=-1)
context(*, assistant_name, query=None, messages=None, filter=None, top_k=None, snippet_size=None, multimodal=None, include_binary_content=None)[source]

Retrieve relevant context snippets from a Pinecone assistant.

Returns the snippets from the assistant’s files that match a text query or a conversation, without generating an answer, so you can prompt your own model with them. Provide exactly one of query or messages.

Parameters:
  • assistant_name (str) – Name of the assistant to retrieve context from.

  • query (str | None) – Text query to use for context retrieval. Mutually exclusive with messages. An empty string is treated as not provided.

  • messages (Sequence[Message | Mapping[str, str]] | None) – Conversation messages to use for context retrieval. Mutually exclusive with query. An empty list is treated as not provided. Dicts are converted to Message objects. Each role is "user" or "assistant".

  • filter (dict[str, Any] | None) – Filter on file metadata, such as {"department": "finance"}, restricting which files contribute snippets.

  • top_k (int | None) – Maximum number of snippets to return. Omit it to let the server choose.

  • snippet_size (int | None) – Maximum size of each snippet, in tokens. Omit it to let the server choose.

  • multimodal (bool | None) – Whether to include snippets drawn from images in files uploaded with multimodal=True.

  • include_binary_content (bool | None) – Whether image snippets include base64 image data. Only meaningful when multimodal is True.

Returns:

ContextResponse with snippets (each carrying content, a relevance score, and a reference naming the source file and, for paginated documents, the pages) and usage.

Raises:
  • PineconeTypeError – If assistant_name is not a str.

  • PineconeValueError – If both or neither of query and messages are provided, or if top_k or snippet_size is negative.

  • ApiError – If the assistant has no file in "Available" status yet, for example while uploads are still processing.

Return type:

ContextResponse

Examples

response = pc.assistants.context(
    assistant_name="research-assistant",
    query="What is Pinecone?",
)
for snippet in response.snippets:
    print(snippet.content)

See also

  • chat(): a generated answer with structured citations, when you want Pinecone to do the generation as well.

  • chat_completions(): a generated answer in OpenAI’s response shape.

chat(*, assistant_name, messages, model='gpt-4o', stream=False, temperature=None, filter=None, json_response=False, include_highlights=False, context_options=None, timeout=None)[source]

Chat with an assistant and receive citations in Pinecone-native format.

Citations come back as a structured list keyed to character positions in the answer, which is what separates this from chat_completions(). The assistant answers only from the files you uploaded to it, so an assistant with nothing ingested yet errors rather than replying from general knowledge.

Parameters:
  • assistant_name (str) – Name of the assistant to chat with.

  • messages (list[Message | dict[str, str]]) – Conversation messages. Dicts are converted to Message objects; role defaults to "user" when not present. Each role is "user" or "assistant".

  • model (str) – Name of the large language model that generates the answer. Defaults to "gpt-4o". The models the API documents for this endpoint are "gpt-4o", "gpt-4.1", "gpt-5", "o4-mini", "claude-sonnet-4-5", and "gemini-2.5-pro". A name outside that list may be served by a successor model rather than rejected, so the response’s model field, not this argument, says which model answered.

  • stream (bool) – If True, return a ChatStream. Defaults to False.

  • temperature (float | None) – Controls randomness. Lower values produce more deterministic responses.

  • filter (dict[str, Any] | None) – Filter on file metadata, such as {"department": "finance"}, restricting which files the answer draws on.

  • json_response (bool) – If True, instruct the assistant to return a JSON response. Cannot be combined with stream=True.

  • include_highlights (bool) – If True, include highlight snippets from referenced documents in citations.

  • context_options (ContextOptions | dict[str, Any] | None) – Retrieval settings, such as top_k and snippet_size, as a ContextOptions or an equivalent dict.

  • timeout (float | None) – Per-call HTTP timeout in seconds, overriding the client-level default. On a streaming request this bounds the gap between chunks rather than the whole response (see below).

Returns:

ChatResponse for non-streaming requests, carrying message (the answer), citations (each with the position in the answer it supports and the references behind it), model (the model that answered), finish_reason and usage. For streaming requests, a ChatStream.

Raises:
  • PineconeTypeError – If assistant_name is not a str.

  • PineconeValueError – If both stream=True and json_response=True are specified.

  • ApiError – If the assistant has no file in "Available" status yet, for example while uploads are still processing.

Return type:

ChatResponse | ChatStream

Examples

from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")
response = pc.assistants.chat(
    assistant_name="research-assistant",
    messages=[{"content": "What is Pinecone?"}],
)
print(response.message.content)
for citation in response.citations:
    for reference in citation.references:
        print(citation.position, reference.file.name)

Set stream=True for a ChatStream instead of a single response. Its text() method yields content fragments as they arrive, skipping the start, citation and end chunks:

stream = pc.assistants.chat(
    assistant_name="research-assistant",
    messages=[{"content": "What is Pinecone?"}],
    stream=True,
)
for text in stream.text():
    print(text, end="", flush=True)

See also

  • chat_completions(): the same conversation in OpenAI’s response shape, with citations woven into the message text instead of returned as a structured list.

  • context(): the retrieved snippets on their own, with no generated answer, when you want to prompt your own model.

Note

On a streaming request the timeout applies to the gap between chunks rather than the whole response, and the default is raised so a model that thinks for a while isn’t mistaken for a dead connection. Pass timeout to change it. A stream that exceeds its timeout raises PineconeTimeoutError partway through iteration, after earlier chunks have already been yielded.

chat_completions(*, assistant_name, messages, model='gpt-4o', stream=False, temperature=None, filter=None, timeout=None)[source]

Chat with an assistant using an OpenAI-compatible interface.

Use it when your code already consumes OpenAI’s chat completion shape. Citations arrive inline in the message text rather than as a structured list, and the include_highlights, context_options and json_response options of chat() are not available.

Parameters:
  • assistant_name (str) – Name of the assistant to chat with.

  • messages (list[Message | dict[str, str]]) – Conversation messages. Dicts are converted to Message objects; role defaults to "user" when not present. Each role is "user" or "assistant".

  • model (str) – Name of the large language model that generates the answer. Defaults to "gpt-4o". The models the API documents for this endpoint are "gpt-4o", "gpt-4.1", "o4-mini", "claude-sonnet-4-5", and "gemini-2.5-pro". A name outside that list may be served by a successor model rather than rejected, so the response’s model field, not this argument, says which model answered.

  • stream (bool) – If True, return a ChatCompletionStream. Defaults to False.

  • temperature (float | None) – Controls randomness. Lower values produce more deterministic responses.

  • filter (dict[str, Any] | None) – Filter on file metadata, such as {"department": "finance"}, restricting which files the answer draws on.

  • timeout (float | None) – Per-call HTTP timeout in seconds, overriding the client-level default. On a streaming request this bounds the gap between chunks rather than the whole response (see below).

Returns:

ChatCompletionResponse for non-streaming requests, carrying choices (read choices[0].message.content for the answer, with citations woven into that text), model (the model that answered), and usage. For streaming requests, a ChatCompletionStream.

Raises:
  • PineconeTypeError – If assistant_name is not a str.

  • ApiError – If the assistant has no file in "Available" status yet, for example while uploads are still processing.

Return type:

ChatCompletionResponse | ChatCompletionStream

Examples

from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")
response = pc.assistants.chat_completions(
    assistant_name="research-assistant",
    messages=[{"content": "Explain quantum entanglement briefly."}],
)
print(response.choices[0].message.content)

Set stream=True for a ChatCompletionStream. Its text() method yields content fragments as they arrive:

stream = pc.assistants.chat_completions(
    assistant_name="research-assistant",
    messages=[{"content": "Explain quantum entanglement briefly."}],
    stream=True,
)
for text in stream.text():
    print(text, end="", flush=True)

See also

  • chat(): the Pinecone-native shape, with a structured citations list.

  • context(): the retrieved snippets on their own, with no generated answer.

Note

On a streaming request the timeout applies to the gap between chunks rather than the whole response, and the default is raised so a model that pauses for longer while reasoning isn’t mistaken for a dead connection. Pass timeout to widen it further. A stream that exceeds its timeout raises PineconeTimeoutError partway through iteration, after earlier chunks have already been yielded.

evaluate_alignment(*, question, answer, ground_truth_answer)[source]

Evaluate answer alignment against a ground truth answer.

Scores a generated answer, such as one from chat(), against an answer you know is right. Alignment is the harmonic mean of correctness (precision) and completeness (recall).

Parameters:
  • question (str) – The question for which the answer was generated.

  • answer (str) – The generated answer to evaluate.

  • ground_truth_answer (str) – The ground truth answer to compare against.

Returns:

AlignmentResult with scores (correctness, completeness and alignment), facts (the per-fact entailment verdicts behind the scores) and token usage.

Return type:

AlignmentResult

Examples

The answer below contradicts the ground truth on purpose, so the scores come back low and result.facts records where the contradiction is:

>>> result = pc.assistants.evaluate_alignment(
...     question="What is the capital of Spain?",
...     answer="Barcelona.",
...     ground_truth_answer="Madrid.",
... )
>>> result.scores.alignment
0.0
>>> [fact.entailment for fact in result.facts]
['contradicted']

Retry configuration

RetryConfig is a constructor argument on Pinecone and AsyncPinecone. See Retries and Resilience for which calls it governs and which run on fixed policy.

class pinecone.RetryConfig(max_retries=3, backoff_factor=0.25, max_wait=60.0, retryable_status_codes=<factory>, on_throttle=None)[source]

Bases: object

Configuration for HTTP retry behavior.

Parameters:
  • max_retries (int) – Number of retries after the initial attempt. Defaults to 3 (4 total attempts).

  • backoff_factor (float) – Minimum delay floor in seconds between retries. The decorrelated-jitter algorithm samples from uniform(backoff_factor, prev_delay * 3) capped at max_wait. Defaults to 0.25.

  • max_wait (float) – Maximum backoff delay in seconds. Defaults to 60.0.

  • retryable_status_codes (frozenset[int]) – HTTP status codes that trigger a retry. Defaults to {408, 429, 500, 502, 503, 504}.

  • on_throttle (Callable[[str], None] | None) – Internal SDK callback invoked with the request URL host on every retryable response (including ones that will be retried). Used by the SDK to wire adaptive concurrency limiters; not intended for user configuration.

max_retries: int = 3
backoff_factor: float = 0.25
max_wait: float = 60.0
retryable_status_codes: frozenset[int]
on_throttle: Callable[[str], None] | None = None
__init__(max_retries=3, backoff_factor=0.25, max_wait=60.0, retryable_status_codes=<factory>, on_throttle=None)
Parameters:
  • max_retries (int)

  • backoff_factor (float)

  • max_wait (float)

  • retryable_status_codes (frozenset[int])

  • on_throttle (Callable[[str], None] | None)

Return type:

None

Resolved configuration

pc.config returns the PineconeConfig a client resolved at construction, with environment variables and defaults folded in. Read it to confirm which host and settings a client uses; pass settings to the Pinecone constructor rather than building one yourself.

class pinecone.PineconeConfig(api_key='', host='', timeout=30.0, additional_headers=<factory>, source_tag='', proxy_url='', proxy_headers=<factory>, ssl_ca_certs=None, ssl_verify=True, grpc_scheme=None, connection_pool_maxsize=0, retry_config=<factory>)[source]

Bases: object

SDK configuration with environment variable fallbacks.

Parameters:
  • api_key (str) – Pinecone API key. Falls back to PINECONE_API_KEY env var.

  • host (str) – API host URL. Falls back to PINECONE_CONTROLLER_HOST env var.

  • timeout (float) – Request timeout in seconds. Defaults to 30.

  • additional_headers (dict[str, str]) – Extra headers to include in every request.

  • source_tag (str) – Source tag for User-Agent string.

  • proxy_url (str) – HTTP proxy URL.

  • ssl_ca_certs (str | None) – Path to CA certificate bundle.

  • ssl_verify (bool) – Whether to verify SSL certificates.

  • grpc_scheme (Literal['http', 'https'] | None) – URL scheme used to dial the gRPC data plane, "http" or "https". Falls back to the PINECONE_GRPC_SCHEME env var, then to None, which lets the gRPC client keep its own default. Dialling "http" against a host outside loopback and the RFC 1918 private ranges warns once per process, since the API key and every payload then cross a public network unencrypted.

  • proxy_headers (dict[str, str])

  • connection_pool_maxsize (int)

  • retry_config (RetryConfig)

api_key: str = ''
host: str = ''
timeout: float = 30.0
additional_headers: dict[str, str]
source_tag: str = ''
proxy_url: str = ''
proxy_headers: dict[str, str]
ssl_ca_certs: str | None = None
ssl_verify: bool = True
grpc_scheme: Literal['http', 'https'] | None = None
connection_pool_maxsize: int = 0
retry_config: RetryConfig
__init__(api_key='', host='', timeout=30.0, additional_headers=<factory>, source_tag='', proxy_url='', proxy_headers=<factory>, ssl_ca_certs=None, ssl_verify=True, grpc_scheme=None, connection_pool_maxsize=0, retry_config=<factory>)
Parameters:
Return type:

None