Schema Builder

SchemaBuilder for constructing index schemas (2026-07 create-schema rules).

Returns a plain {"fields": {...}} dict (not a model) so forward-compatible fields the SDK does not yet model can pass through unmodified.

Create-schema rules at API version 2026-07:

  • Every schema must declare at least one searched field: dense_vector, sparse_vector, or string with full_text_search.

  • At most one dense_vector and at most one sparse_vector field per schema (server-enforced).

  • On managed and BYOC indexes, metadata-only field declarations (boolean, float, string_list, and string without full_text_search) are rejected by the server — metadata is indexed automatically at upsert time. Pod indexes are the exception: they still accept metadata field declarations.

  • semantic_text fields are not accepted in create schemas at 2026-07 and the builder does not offer a method for them.

  • integer is a response-only field type: it appears in describe/list responses for indexes that pre-date numeric normalisation, but the create schema has no integer variant and the server rejects one with a 422. The builder offers no method for it and refuses it client-side wherever a raw field dict can carry a type key (see SchemaBuilder.add_custom_field() and the additional_options parameters), so a describe-then-create round-trip fails locally with an explanatory error instead of a server 422.

class pinecone.schema_builder.SchemaBuilder[source]

Bases: object

Fluent builder for index schema dicts (API version 2026-07).

Each add_* method appends or replaces a field definition and returns self so calls can be chained. Call build() at the end to obtain the {"fields": {...}} dict.

Adding a field whose name already exists silently replaces the previous definition (last writer wins).

A create schema declares the fields that are searched: a dense vector field, a sparse vector field, or string fields with full-text search enabled. On managed and BYOC indexes, every other field type is metadata — include those values in documents instead of the schema and they are indexed for filtering automatically at upsert time. Pod indexes still accept metadata field declarations (add_boolean_field(), add_float_field(), add_string_list_field(), and add_string_field() without full-text search).

There is no add_integer_field. integer is a response-only field type at 2026-07 — it is returned by describe/list but has no create variant — so the builder rejects it wherever a raw type key can reach a field dict (add_custom_field(), or additional_options), raising PineconeValueError rather than letting the server answer with a 422. Use add_float_field() for numeric fields.

Examples

>>> from pinecone.schema_builder import SchemaBuilder
>>> schema = (
...     SchemaBuilder()
...     .add_dense_vector_field("embedding", dimension=768, metric="cosine")
...     .add_string_field("title", full_text_search={"language": "en"})
...     .build()
... )
__init__()[source]
Return type:

None

add_dense_vector_field(name, *, dimension, metric, description=None, **additional_options)[source]

Add a dense vector field for similarity search.

A schema may contain at most one dense vector field; the server rejects schemas with more than one.

Parameters:
  • name (str) – Field name. Replaces any existing field with the same name.

  • dimension (int) – Vector dimensionality. Must be between 1 and 20000 inclusive; values outside that range are rejected client-side.

  • metric (str) – Distance metric — "cosine", "euclidean", or "dotproduct".

  • description (str | None) – Optional human-readable description.

  • **additional_options (Any) – Extra parameters merged into the field dict last, for forward compatibility with new API features.

Returns:

self for method chaining.

Raises:

PineconeValueError – If dimension is outside the range 1–20000 inclusive.

Return type:

SchemaBuilder

add_sparse_vector_field(name, *, description=None, **additional_options)[source]

Add a sparse vector field for keyword-weighted or learned-sparse search.

The wire type is "sparse_vector", and description is the only other key a create schema accepts on it. A sparse vector field has no metric — sparse scoring is not configurable — and no dimension, because sparse vectors are variable-length. Passing either raises instead of putting a key on the wire that configures nothing.

A schema may contain at most one sparse vector field; the server rejects schemas with more than one.

Parameters:
  • name (str) – Field name. Replaces any existing field with the same name.

  • description (str | None) – Optional human-readable description.

  • **additional_options (Any) – Extra parameters merged into the field dict last, for forward compatibility with new API features.

Returns:

self for method chaining.

Raises:

PineconeValueError – If metric or dimension is passed — a sparse vector field has neither.

Return type:

SchemaBuilder

Examples

schema = (
    SchemaBuilder()
    .add_dense_vector_field("embedding", dimension=1536, metric="dotproduct")
    .add_sparse_vector_field("sparse_terms")
    .build()
)
add_string_field(name, *, full_text_search=None, language=None, stemming=None, stop_words=None, filterable=False, description=None, **additional_options)[source]

Add a string field for full-text search (or, on pod indexes, filtering).

Full-text search is enabled by passing full_text_search=True, a full_text_search dict, or any of the typed FTS keyword arguments (language, stemming, stop_words).

Important

At API version 2026-07, a string field’s shape decides which deployment family accepts it. Without full_text_search, it is a metadata-only declaration: pod indexes accept it as filterable metadata, while managed and BYOC indexes reject it (400: the schema only accepts fields used for search). With full_text_search, it is the other way around: managed and BYOC indexes accept it, while pod indexes reject it (400: full-text-search fields are not supported for that deployment type). For managed and BYOC indexes, omit metadata-only fields from the schema and include the values in documents instead; they are indexed for filtering automatically at upsert time.

When both full_text_search dict and keyword arguments are provided, the keyword arguments take precedence for the same key.

lowercase and max_term_len are server-managed and cannot be configured via the SDK.

Parameters:
  • name (str) – Field name. Replaces any existing field with the same name.

  • full_text_search (bool | dict[str, Any] | None) – True or {} to enable FTS with server defaults, a dict of FTS-config keys (language, stemming, stop_words, ngram), or None (default) to leave FTS disabled — valid only for pod indexes; see the note above.

  • language (str | None) – Language for FTS tokenisation and analysis. Accepts ISO short codes or long-form aliases. Both "en" and "english" are valid; the SDK normalises known long-form aliases to the short-code form on the wire. Codes known to the SDK at this version: ar, da, de, el, en, es, fi, fr, hu, it, nl, no, pt, ro, ru, sv, ta, tr (and their long-form aliases: arabic, danish, german, greek, english, spanish, finnish, french, hungarian, italian, dutch, norwegian, portuguese, romanian, russian, swedish, tamil, turkish). The SDK does not validate this value against that list — unknown codes are passed through unchanged so newly-supported languages work without an SDK upgrade. The server is the source of truth.

  • stemming (bool | None) – Enable word stemming. Required when stop_words=True.

  • stop_words (bool | None) – Enable stop-word filtering. Requires stemming=True. Not all languages support stop words; the server will reject unsupported combinations — the SDK does not pre-validate that rule.

  • filterable (bool) – Enable metadata-filter support. Sent on the wire, including the False default, unless full_text_search is also enabled and filterable was not requested. On create, a string field is either searchable or filterable, never both: passing filterable=True alongside full_text_search makes the server keep the filter and discard the search configuration, and it reports no error for doing so.

  • description (str | None) – Optional human-readable description.

  • **additional_options (Any) – Extra parameters merged into the field dict last, for forward compatibility with new API features.

Returns:

self for method chaining.

Raises:

PineconeValueError – If stop_words=True is requested without stemming=True, or if an ngram config is combined with stemming=True or stop_words=True.

Return type:

SchemaBuilder

Examples

# Enable FTS with server defaults:
builder.add_string_field("title", full_text_search=True)

# Enable FTS with explicit kwargs:
builder.add_string_field(
    "title", language="en", stemming=True, stop_words=True
)

# Character n-gram tokenization (e.g. substring/autocomplete):
builder.add_string_field(
    "title",
    full_text_search={"ngram": {"min_gram": 2, "max_gram": 3}},
)
add_string_list_field(name, *, filterable=False, description=None, **additional_options)[source]

Add a list-of-strings field for metadata filtering (pod indexes only).

Important

At API version 2026-07, string_list is a metadata-only declaration, and the server rejects it when creating managed or BYOC indexes (400: the schema only accepts fields used for search) — regardless of filterable. Pod indexes are the exception and still accept this declaration. For managed and BYOC indexes, include list-of-string values in documents instead; they are indexed for filtering automatically at upsert time.

String-list fields store a list of strings per row — useful for tag-style metadata (e.g. ["sci-fi", "mystery"]) that should be filterable against individual elements.

The wire type is "string_list".

Parameters:
  • name (str) – Field name. Replaces any existing field with the same name.

  • filterable (bool) – Enable metadata-filter support. Always included in the built schema, whether True or False.

  • description (str | None) – Optional human-readable description.

  • **additional_options (Any) – Extra parameters merged into the field dict last, for forward compatibility with new API features.

Returns:

self for method chaining.

Return type:

SchemaBuilder

Examples

builder.add_string_list_field("tags", filterable=True)
add_boolean_field(name, *, filterable=False, description=None, **additional_options)[source]

Add a boolean field for metadata filtering (pod indexes only).

Important

At API version 2026-07, boolean is a metadata-only declaration, and the server rejects it when creating managed or BYOC indexes (400: the schema only accepts fields used for search) — regardless of filterable. Pod indexes are the exception and still accept this declaration. For managed and BYOC indexes, include boolean values in documents instead; they are indexed for filtering automatically at upsert time.

The wire type is "boolean".

Parameters:
  • name (str) – Field name. Replaces any existing field with the same name.

  • filterable (bool) – Enable metadata-filter support on this field. Always included in the built schema, whether True or False.

  • description (str | None) – Optional human-readable description.

  • **additional_options (Any) – Extra parameters merged into the field dict last, for forward compatibility with new API features.

Returns:

self for method chaining.

Return type:

SchemaBuilder

Examples

builder.add_boolean_field("is_published", filterable=True)
add_float_field(name, *, filterable=False, description=None, **additional_options)[source]

Add a numeric field for metadata filtering (pod indexes only).

Important

At API version 2026-07, float is a metadata-only declaration, and the server rejects it when creating managed or BYOC indexes (400: the schema only accepts fields used for search) — regardless of filterable. Pod indexes are the exception and still accept this declaration. For managed and BYOC indexes, include numeric values in documents instead; they are indexed for filtering automatically at upsert time.

The wire type is "float" — the only numeric type a create schema accepts. The create schema has no integer type; integers are stored and filtered as double-precision floats. (Describe/list responses can still return integer for indexes that pre-date that normalisation; see IntegerField.)

Parameters:
  • name (str) – Field name. Replaces any existing field with the same name.

  • filterable (bool) – Enable filtering on this field. Always included in the built schema, whether True or False.

  • description (str | None) – Optional human-readable description.

  • **additional_options (Any) – Extra parameters merged into the field dict last, for forward compatibility with new API features.

Returns:

self for method chaining.

Return type:

SchemaBuilder

add_custom_field(name, field_definition)[source]

Escape hatch — store a raw field dict verbatim.

Use when you need a field type the SDK does not yet model, or when experimenting with new API features before the SDK adds support. The field name is validated and the definition’s type is checked against the response-only types listed below; nothing else about the definition is validated.

Important

{"type": "integer"} is rejected client-side. integer is a response-only field type: it comes back from describe/list for indexes created before numeric values were normalised to float, but the 2026-07 create schema has no integer variant and the server answers a create request carrying one with a 422. When replaying a described schema into a create request, drop integer fields (numeric metadata is indexed for filtering automatically at upsert time) or, on a pod index, declare them with add_float_field().

Parameters:
  • name (str) – Field name. Replaces any existing field with the same name.

  • field_definition (dict[str, Any]) – Complete field definition dict; stored as-is.

Returns:

self for method chaining.

Raises:

PineconeValueError – If the field name is invalid, or if field_definition["type"] is a response-only type such as "integer".

Return type:

SchemaBuilder

build()[source]

Return the completed schema dict.

Returns a copy of the internal field dict so that subsequent add_* calls do not mutate a previously built result.

The server requires at least one searched field (dense_vector, sparse_vector, or string with full_text_search) per schema; the builder does not enforce that here so partial schemas can be built and inspected.

Returns:

{"fields": {name: field_dict, ...}} ready to pass as the schema argument when creating an index.

Return type:

dict[str, dict[str, Any]]