Admin

The Admin client manages organizations, projects, API keys, users, invites, service accounts, and role bindings. It uses OAuth2 client credentials (service account) rather than an API key, and is the right tool for control-plane operations such as creating projects and rotating keys. It is synchronous only — there is no async form of this client.

The users, invites, service-account, and role-binding namespaces are new in 2026-07. See the Admin and OAuth section of Migrating to V10 for the per-operation release notes and an end-to-end RBAC walkthrough.

class pinecone.admin.Admin(*, client_id=None, client_secret=None, additional_headers=None, proxy_url=None, ssl_verify=True, source_tag=None, host=None, oauth_url=None)[source]

Bases: object

Admin client for Pinecone organization and project management.

Auth model: Admin uses OAuth2 client credentials (service account), while Pinecone uses API keys. These serve different purposes:

  • Admin — organization/project/key management (create projects, rotate keys, etc.)

  • Pinecone — index and vector operations (upsert, query, etc.)

A common workflow bridges both: use Admin to create a project and API key, then pass that key to Pinecone for data-plane operations:

from pinecone import Admin, Pinecone

admin = Admin(client_id="...", client_secret="...")
project = admin.projects.create(name="my-project")
key = admin.api_keys.create(project_id=project.id, name="my-key")
pc = Pinecone(api_key=key.value)
pc.indexes.create(
    name="my-index",
    schema={"fields": {"values": {"type": "dense_vector",
                                  "dimension": 1536, "metric": "cosine"}}},
    deployment={"deployment_type": "managed", "cloud": "aws", "region": "us-east-1"},
)

Projects are created within the organization associated with your OAuth credentials.

Operations are grouped into seven namespaces:

  • organizations — the organizations these credentials can reach

  • projects — create, configure, and delete projects

  • api_keys — the project-scoped keys Pinecone authenticates with

  • users — the organization’s members

  • invites — pending and expired invitations to join the organization

  • service_accounts — the OAuth principals this client itself authenticates as

  • role_bindings — every grant of a role to a principal, at organization or project scope; nothing else confers permissions

Note

Obtaining OAuth credentials — a service account’s client_id and client_secret can come from either of two places:

  • admin.service_accounts.create(), once you already hold admin credentials. The client_secret is returned exactly once, at creation, and rotate_secret() is the only way to obtain another.

  • The Pinecone console, under organization settings. This is how the first pair is obtained, since there is nothing to authenticate an Admin with until one service account exists.

These differ from the API keys used by Pinecone; they are scoped to your organization and used exclusively for admin operations.

Note

Token refreshAdmin renews its OAuth token automatically before it expires, so a long-lived instance keeps working without any action on your part. Supply your own Authorization entry in additional_headers to manage the token yourself instead.

Note

Admin is synchronous only. There is no async form of this client; admin operations are infrequent control-plane calls, and AsyncPinecone is where the async lane lives.

Parameters:
  • client_id (str | None) – OAuth2 client ID. Falls back to PINECONE_CLIENT_ID env var.

  • client_secret (str | None) – OAuth2 client secret. Falls back to PINECONE_CLIENT_SECRET env var.

  • additional_headers (dict[str, str] | None) – Extra headers included in every admin API request. Merged last, so an entry keyed exactly "Authorization" or "X-Pinecone-Api-Version" replaces the header the SDK would otherwise send for that name. Matching is case-sensitive: any other spelling is sent alongside the SDK’s own header rather than replacing it.

  • proxy_url (str | None) – HTTP proxy URL for outgoing requests.

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

  • source_tag (str | None) – Tag appended to the User-Agent string for request attribution.

  • host (str | None) – Admin API host. Falls back to PINECONE_CONTROLLER_HOST env var, then defaults to https://api.pinecone.io. A value with no scheme is prefixed with https://, matching Pinecone. Intended for pointing the client at a local simulator in tests or at a private Pinecone deployment; leave it unset against production.

  • oauth_url (str | None) – Full URL of the OAuth2 token endpoint, including its path. Defaults to https://login.pinecone.io/oauth/token. A value with no scheme is prefixed with https://. Intended for pointing the token exchange at a local simulator in tests or at a private Pinecone deployment; leave it unset against production. There is no environment-variable fallback for this parameter.

Raises:

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for org in admin.organizations.list():
...     print(org.name)
__init__(*, client_id=None, client_secret=None, additional_headers=None, proxy_url=None, ssl_verify=True, source_tag=None, host=None, oauth_url=None)[source]
Parameters:
  • client_id (str | None)

  • client_secret (str | None)

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

  • proxy_url (str | None)

  • ssl_verify (bool)

  • source_tag (str | None)

  • host (str | None)

  • oauth_url (str | None)

Return type:

None

property api_keys: ApiKeys

Access the ApiKeys namespace for API key operations.

API keys are project-scoped credentials that Pinecone authenticates with for data-plane operations. Created on first access and cached for the life of this client.

Returns:

The ApiKeys namespace. Call create() or list() to create or look up keys for a project.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> keys = admin.api_keys.list(project_id="proj-abc123")
>>> for key in keys:
...     print(key.key.id)
close()[source]

Close the underlying HTTP client, releasing its connections.

Call this when you’re done with an Admin instance that isn’t used as a context manager. Further calls through any of its namespaces will fail.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> admin.close()
Return type:

None

property invites: Invites

Access the Invites namespace for organization-invite operations.

Created on first access and cached for the life of this client.

Returns:

The Invites namespace. Call create() or list() to invite someone to the organization or look up pending invites.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for invite in admin.invites.list():
...     print(invite.email, invite.status)
property organizations: Organizations

Access the Organizations namespace for organization operations.

Organizations are the top-level container for projects, users, and billing in Pinecone. Created on first access and cached for the life of this client.

Returns:

The Organizations namespace. Call list() or describe() to look up organizations reachable with the current credentials.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for org in admin.organizations.list():
...     print(org.name)
property projects: Projects

Access the Projects namespace for project operations.

Created on first access and cached for the life of this client.

Returns:

The Projects namespace. Call create() or list() to create or look up projects.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for project in admin.projects.list():
...     print(project.name)
property role_bindings: RoleBindings

Access the RoleBindings namespace for role-binding operations.

Role bindings are the only thing that confers permissions in Pinecone, so this is where any principal’s access — user, service account, API key, or pending invite — is read and changed. Created on first access and cached for the life of this client.

Returns:

The RoleBindings namespace. Call create() or list() to grant a role or look up existing grants.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for binding in admin.role_bindings.list():
...     print(binding.principal_id, binding.role, binding.resource_id)
property service_accounts: ServiceAccounts

Access the ServiceAccounts namespace for service-account operations.

Service accounts are the OAuth principals Admin clients authenticate as, including the one behind this client’s own client_id/client_secret — rotating or deleting that account breaks this client. Created on first access and cached for the life of this client.

Returns:

The ServiceAccounts namespace. Call create() or list() to create or look up service accounts.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for account in admin.service_accounts.list():
...     print(account.id, account.name)
property users: Users

Access the Users namespace for organization-member operations.

Created on first access and cached for the life of this client.

Returns:

The Users namespace. Call list() to look up the organization’s members.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for user in admin.users.list():
...     print(user.email)

Organizations

class pinecone.admin.organizations.Organizations(*, http)[source]

Bases: object

Operations on Pinecone organizations.

An organization is the top-level account boundary in Pinecone: it holds projects, users, and billing. This namespace lists, describes, updates, and deletes organizations.

Parameters:

http (HTTPClient) – HTTP client for making API requests.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="my-id", client_secret="my-secret")
>>> for org in admin.organizations.list():
...     print(org.name)
__init__(*, http)[source]
Parameters:

http (HTTPClient)

Return type:

None

delete(*, organization_id)[source]

Delete an organization.

An organization must meet three conditions before it can be deleted:

  • It is not on a paid plan (downgrade first).

  • Its payment status is active, with no open invoices.

  • It contains no projects (see Projects.delete).

All three must hold at once — an organization with no projects can still be blocked by its plan or payment status.

Parameters:

organization_id (str) – The organization’s identifier, e.g. "org-abc123".

Raises:
  • PineconeValueError – If organization_id is empty.

  • FailedPreconditionError – If the organization is on a paid plan, its payment status is not active, or it still contains projects. The error message names the blocker.

  • ApiError – If the API returns an error response.

Return type:

None

Examples

>>> admin.organizations.delete(organization_id="org-abc123")
describe(*, organization_id)[source]

Get details for one organization.

Parameters:

organization_id (str) – The organization’s identifier, e.g. "org-abc123".

Returns:

An OrganizationModel with the organization’s name, plan, payment status, support tier, and creation time.

Raises:
Return type:

OrganizationModel

Examples

>>> org = admin.organizations.describe(organization_id="org-abc123")
>>> org.name
'Acme Corp'
list()[source]

List the organizations your credentials can access.

Returns:

An OrganizationList supporting iteration, len(), and index access.

Raises:

ApiError – If the API returns an error response.

Return type:

OrganizationList

Examples

>>> admin = Admin(client_id="my-id", client_secret="my-secret")
>>> for org in admin.organizations.list():
...     print(org.name)
update(*, organization_id, name)[source]

Rename an organization.

Parameters:
  • organization_id (str) – The organization’s identifier, e.g. "org-abc123".

  • name (str) – The new name for the organization, e.g. "Acme Corp".

Returns:

An OrganizationModel with the updated organization details.

Raises:
Return type:

OrganizationModel

Examples

>>> org = admin.organizations.update(
...     organization_id="org-abc123", name="New Name"
... )
>>> org.name
'New Name'

Projects

class pinecone.admin.projects.Projects(*, http, admin=None)[source]

Bases: object

Operations on Pinecone projects.

A project is the boundary for resource quotas and API keys within an organization: indexes, collections, backups, and API keys all belong to exactly one project. This namespace lists, creates, describes, updates, and deletes projects.

Parameters:
  • http (HTTPClient) – HTTP client for making API requests.

  • admin (Admin | None)

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for project in admin.projects.list():
...     print(project.name)
__init__(*, http, admin=None)[source]
Parameters:
  • http (HTTPClient)

  • admin (Admin | None)

Return type:

None

create(*, name, max_pods=None, force_encryption_with_cmek=None)[source]

Create a new project.

Parameters:
  • name (str) – Name for the new project, e.g. "my-project" (1-512 characters, no null bytes).

  • max_pods (int | None) – Maximum number of pods allowed in the project. Pod-based capacity is legacy: unless the organization already has pod access, only 0 (the default, meaning serverless-only) is accepted, and a non-zero value is rejected. Omitted if None.

  • force_encryption_with_cmek (bool | None) – Whether to enforce CMEK encryption for the project. Requesting True requires CMEK to be enabled for the organization; False and None are always accepted. Omitted if None.

Returns:

A ProjectModel with the created project details.

Raises:
  • PineconeValueError – If name is empty, exceeds 512 characters, or contains null bytes.

  • PaymentRequiredError – If the organization’s billing state does not permit creating a project.

  • ForbiddenError – If the organization has reached its project quota, or if force_encryption_with_cmek was requested without CMEK enabled for the organization.

  • ApiError – If the API returns an error response — including a non-zero max_pods requested without pod access.

Return type:

ProjectModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> project = admin.projects.create(name="my-project")
>>> project.name
'my-project'
delete(*, project_id)[source]

Delete a project.

The project must be empty first. Indexes, collections, assistants, and backups all block deletion, and the error names what is still there. API keys are not a blocker — they are deleted along with the project.

delete_with_cleanup() clears all of them for you.

Parameters:

project_id (str) – The identifier of the project to delete, e.g. "proj-abc123".

Raises:
Return type:

None

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> admin.projects.delete(project_id="proj-abc123")
delete_with_cleanup(*, project_id, max_attempts=5, retry_delay=30.0)[source]

Delete a project after cleaning up all its resources.

Creates a temporary API key scoped to the project, uses it to delete every index, collection, assistant, and backup, then deletes the temporary key and finally deletes the project itself.

The cleanup is retried up to max_attempts times with retry_delay seconds between attempts to handle transient failures.

Creating the temporary key is the first thing this method does, so a project whose API-key quota is already full cannot be cleaned up: the error names the quota as the blocker and nothing is deleted. Free a key slot and call again.

Cleanup covers every resource that blocks a project delete. It is not atomic, though: a resource created in the project while cleanup is running can still leave the final delete blocked.

Parameters:
  • project_id (str) – The identifier of the project to delete, e.g. "proj-abc123".

  • max_attempts (int) – Maximum number of cleanup attempts. Defaults to 5.

  • retry_delay (float) – Seconds to wait between retry attempts. Defaults to 30.0.

Raises:
  • PineconeError – If no admin back-reference is available — call this through admin.projects.delete_with_cleanup(...) rather than constructing Projects directly.

  • PineconeValueError – If project_id is empty.

  • ForbiddenError – If the temporary API key cannot be created — typically because the project’s API-key quota is exhausted. No resources are deleted in this case.

  • FailedPreconditionError – If the project is still not empty when the final delete runs, which happens when something is created in it after cleanup finishes. The error names what is blocking.

  • ApiError – If resource cleanup or project deletion fails after all retries.

Return type:

None

Examples

from pinecone import Admin
admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
admin.projects.delete_with_cleanup(project_id="proj-abc123")
describe(*, project_id)[source]

Get details for one project.

Parameters:

project_id (str) – The project’s identifier, e.g. "proj-abc123".

Returns:

A ProjectModel with the project’s name, quotas, and organization.

Raises:
Return type:

ProjectModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> project = admin.projects.describe(project_id="proj-abc123")
>>> project.name
'my-project'
describe_by_name(*, name)[source]

Get details for one project by name.

Lists all projects accessible to the authenticated user and filters client-side for an exact name match.

Parameters:

name (str) – The project’s name, e.g. "my-project".

Returns:

A ProjectModel with the project’s name, quotas, and organization.

Raises:
Return type:

ProjectModel

Examples

from pinecone import Admin
admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
project = admin.projects.describe_by_name(name="my-project")
project.id  # 'proj-abc123'
exists(*, project_id=None, name=None)[source]

Check whether a project exists.

Exactly one of project_id or name must be provided.

Parameters:
  • project_id (str | None) – The project’s identifier, e.g. "proj-abc123".

  • name (str | None) – The project’s name, e.g. "my-project".

Returns:

True if the project exists, False otherwise.

Raises:

PineconeValueError – If neither or both arguments are provided.

Return type:

bool

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> admin.projects.exists(project_id="proj-abc123")
True
>>> admin.projects.exists(name="nonexistent")
False
list()[source]

List all projects accessible to the authenticated user.

Returns:

A ProjectList supporting iteration, len(), and index access.

Raises:

ApiError – If the API returns an error response.

Return type:

ProjectList

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for project in admin.projects.list():
...     print(project.name)
update(*, project_id, name=None, max_pods=None, force_encryption_with_cmek=None)[source]

Update a project’s settings.

Parameters:
  • project_id (str) – The identifier of the project to update, e.g. "proj-abc123".

  • name (str | None) – New name for the project. Left unchanged if omitted.

  • max_pods (int | None) – New maximum pod count. Subject to the same pod-access constraint as create(). Left unchanged if omitted.

  • force_encryption_with_cmek (bool | None) – New CMEK enforcement setting. Enabling it requires the same entitlement as create(). CMEK is a one-way door: once a project has it enabled, it cannot be turned back off, and passing False for a project that never had it enabled is a no-op. Left unchanged if omitted.

Returns:

A ProjectModel with the updated project details.

Raises:
  • PineconeValueError – If project_id is empty, or if name is empty, exceeds 512 characters, or contains null bytes.

  • ForbiddenError – If force_encryption_with_cmek is True and CMEK is not enabled for the organization.

  • ApiError – If the API returns an error response — including a non-zero max_pods requested without pod access, or an attempt to turn CMEK back off.

Return type:

ProjectModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> project = admin.projects.update(
...     project_id="proj-abc123", name="new-name"
... )
>>> project.name
'new-name'

API Keys

class pinecone.admin.api_keys.ApiKeys(*, http)[source]

Bases: object

Control-plane operations for Pinecone API keys.

Provides methods to list, create, describe, update, and delete API keys scoped to a project.

Parameters:

http (HTTPClient) – HTTP client for making API requests.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for key in admin.api_keys.list(project_id="proj-abc123"):
...     print(key.name)
__init__(*, http)[source]
Parameters:

http (HTTPClient)

Return type:

None

create(*, project_id, name, roles=None)[source]

Create a new API key for a project.

Parameters:
  • project_id (str) – The identifier of the project.

  • name (str) – Name for the new API key (1-80 characters).

  • roles (list[APIKeyRole | str] | None) –

    Roles to assign to the key. Valid values are "ProjectEditor", "ProjectViewer", "ControlPlaneEditor", "ControlPlaneViewer", "DataPlaneEditor", and "DataPlaneViewer". Defaults to ["ProjectEditor"] if omitted.

    Which of these a key may actually hold depends on the organization’s plan; the more restrictive plans accept "ProjectEditor" only. A role the plan does not permit is refused with a ForbiddenError naming the role and the plan it needs.

Returns:

An APIKeyWithSecret containing the key metadata and secret value. The secret value is only available at creation time.

Raises:
  • PineconeValueError – If project_id or name is empty, or if name exceeds 80 characters.

  • PaymentRequiredError – If the organization’s billing state does not permit creating an API key.

  • ForbiddenError – Either the project has reached its API-key quota, or roles names a role the organization’s plan does not permit (see roles above) — the error message distinguishes the two. Quota exhaustion raises this error rather than RateLimitError.

  • ApiError – If the API returns an error response.

Return type:

APIKeyWithSecret

Examples

>>> from pinecone import Admin, APIKeyRole
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> result = admin.api_keys.create(
...     project_id="proj-abc123", name="prod-search-key",
...     roles=[APIKeyRole.PROJECT_EDITOR]
... )
>>> result.value
'pcsk_abc123_secretvalue'
>>> result = admin.api_keys.create(
...     project_id="proj-abc123", name="ci-pipeline-key", roles=["ProjectViewer"]
... )
>>> result.key.roles
['ProjectViewer']
delete(*, api_key_id)[source]

Delete an API key.

Parameters:

api_key_id (str) – The identifier of the API key to delete.

Raises:
Return type:

None

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> admin.api_keys.delete(api_key_id="key-abc123")
describe(*, api_key_id)[source]

Get detailed information about an API key.

Parameters:

api_key_id (str) – The identifier of the API key.

Returns:

An APIKeyModel with full API key details.

Raises:
Return type:

APIKeyModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> key = admin.api_keys.describe(api_key_id="key-abc123")
>>> key.name
'prod-search-key'
list(*, project_id)[source]

List all API keys for a project.

Parameters:

project_id (str) – The identifier of the project.

Returns:

An APIKeyList supporting iteration, len(), and index access.

Raises:
Return type:

APIKeyList

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for key in admin.api_keys.list(project_id="proj-abc123"):
...     print(key.name)
update(*, api_key_id, name=None, roles=None)[source]

Update an API key’s settings.

When roles is provided, it replaces the entire role set.

Parameters:
  • api_key_id (str) – The identifier of the API key to update.

  • name (str | None) – New name for the API key. Unlike create(), the length limit is not checked locally — an over-long name is rejected by the server instead.

  • roles (list[APIKeyRole | str] | None) – New roles for the API key. Replaces all existing roles. Subject to the same plan-dependent restriction as create().

Returns:

An APIKeyModel with the updated API key details.

Raises:
  • PineconeValueError – If api_key_id is empty.

  • ForbiddenError – If roles names a role the organization’s plan does not permit for API keys. Unlike create(), no API-key quota check applies here.

  • ApiError – If the API returns an error response.

Return type:

APIKeyModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> key = admin.api_keys.update(
...     api_key_id="key-abc123", name="new-name"
... )
>>> key.name
'new-name'

Users

class pinecone.admin.users.Users(*, http)[source]

Bases: object

Control-plane operations for the users in an organization.

Provides methods to list, describe, and remove the members of the organization associated with the Admin client’s OAuth credentials.

Role bindings are not part of a user’s representation. Use the role-binding operations to see or change what a user can do.

Parameters:

http (HTTPClient) – HTTP client for making API requests.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for user in admin.users.list():
...     print(user.email)
__init__(*, http)[source]
Parameters:

http (HTTPClient)

Return type:

None

delete(*, user_id)[source]

Remove a user from the organization.

The user’s role bindings are revoked immediately; their Pinecone account itself is not deleted. This call is not repeatable: once it succeeds, a second call with the same user_id raises NotFoundError, as does describe() for that user.

Parameters:

user_id (str) – The identifier of the user to remove.

Raises:
  • PineconeValueError – If user_id is empty.

  • NotFoundError – If no such user is a member of the organization.

  • ConflictError – If removal would violate an organization invariant, such as dropping the last OrgOwner.

  • ApiError – If the API returns an error response.

Return type:

None

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> admin.users.delete(user_id="e2e92523-85dc-4142-b8c2-e681be8b78df")
describe(*, user_id)[source]

Get detailed information about a user in the organization.

Parameters:

user_id (str) – The identifier of the user.

Returns:

A UserModel with the user’s details.

Raises:
Return type:

UserModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> user = admin.users.describe(user_id="e2e92523-85dc-4142-b8c2-e681be8b78df")
>>> user.email
'alice@example.com'
list(*, email=None, limit=None, pagination_token=None)[source]

List the users in the organization, with transparent lazy pagination.

No request is sent until the returned paginator is iterated. Iterating past the first page automatically follows the cursor from the page before it; iteration stops once a page comes back with no cursor to follow.

Parameters:
  • email (str | None) – Case-insensitive filter on the user’s email address, e.g. "alice@example.com". The SDK does not validate or normalize the value; a malformed address is rejected by the server. Omit to list all users.

  • limit (int | None) – Number of users the server returns per page, between 1 and 100. It caps each page, not how many users the paginator yields in total; the paginator keeps following cursors until the pages run out. Use itertools.islice() to cap the total. When None the parameter is omitted and the server chooses the page size.

  • pagination_token (str | None) – Cursor from a previous call’s paginator (its pagination_token property), to resume where that iteration stopped. Reuse it with the same email and limit.

Returns:

Paginator over UserModel objects. Supports for loops, .to_list(), .pages() for page-level access, and .pagination_token for resumption.

Raises:
  • PineconeValueError – If limit is outside 1-100. Raised before any network call.

  • ApiError – If the API returns an error response.

Return type:

Paginator[UserModel]

Examples

for user in admin.users.list():
    print(user.id, user.email)

matches = admin.users.list(email="alice@example.com").to_list()

for page in admin.users.list(limit=25).pages():
    print(len(page.items), page.pagination_token)

Invites

class pinecone.admin.invites.Invites(*, http)[source]

Bases: object

Operations on organization invites.

An invite is an offer, sent by email, for someone to join the organization; accepting it turns the recipient into a member. This namespace lists, creates, describes, deletes, and resends invites for the organization associated with the Admin client’s OAuth credentials.

An invite’s role bindings are not part of its representation: create sends them, but no method here returns them. Read or change them afterwards through the role-binding operations, filtering on principal_type=invite.

Parameters:

http (HTTPClient) – HTTP client for making API requests.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for invite in admin.invites.list():
...     print(invite.email, invite.status)
__init__(*, http)[source]
Parameters:

http (HTTPClient)

Return type:

None

create(*, email, role_bindings)[source]

Invite a user to the organization and grant their initial role bindings.

On success the server has already sent the invite email; the returned invite is pending, and its expires_at is when it lapses. The response does not echo the role bindings — read them back through the role-binding operations, filtering on principal_type=invite.

Parameters:
  • email (str) – The address to invite, e.g. "newhire@acme.com". The SDK checks only that it isn’t empty; the server validates the address itself and rejects a malformed or over-long one.

  • role_bindings (Sequence[RoleBindingInput | Mapping[str, Any]]) – The roles to grant the invitee, as RoleBindingInput instances or plain dicts, mixed freely. Each entry needs resource_type ("organization" or "project") and role; project scope additionally needs resource_id, the project UUID. At least one entry is required, and the server requires at least one of them to be an organization-scoped membership role (OrgOwner, OrgManager, OrgBillingAdmin, or OrgMember).

Returns:

The created InviteModel.

Raises:
  • PineconeValueError – If email is empty, if role_bindings is empty, or if any entry is missing resource_type/role, carries an unrecognized key, or names a value this SDK release does not know. The message names the index of the offending entry. Raised before any network call.

  • ConflictError – If a pending invite already exists for the address, or the address already belongs to an organization member.

  • ApiError – If the API returns an error response.

Return type:

InviteModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> invite = admin.invites.create(
...     email="newhire@acme.com",
...     role_bindings=[{"resource_type": "organization", "role": "OrgMember"}],
... )

Typed inputs and dicts are interchangeable, and may be mixed:

from pinecone.models.admin import ResourceType, RoleBindingInput, RoleName

admin.invites.create(
    email="newhire@acme.com",
    role_bindings=[
        RoleBindingInput(
            resource_type=ResourceType.ORGANIZATION,
            role=RoleName.ORG_MEMBER,
        ),
        {
            "resource_type": "project",
            "role": "ProjectViewer",
            "resource_id": "a2f7dddb-1597-4eff-9f71-535fde243f58",
        },
    ],
)
delete(*, invite_id)[source]

Delete a pending or expired invite, along with its role bindings.

By the time this call returns, the invite and its role bindings are gone — a repeat call, or fetching it by ID afterwards, gets a not-found error. An invite that has already been accepted can’t be deleted this way: remove the resulting member with admin.users.delete instead.

Parameters:

invite_id (str) – The identifier of the invite to delete.

Raises:
Return type:

None

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> admin.invites.delete(
...     invite_id="9c8e3528-b9c0-4358-84ce-84c28e91b566"
... )
describe(*, invite_id)[source]

Get detailed information about one invite, whatever its status.

Unlike list(), this reaches processed invites too — it is the only operation that can return status == InviteStatus.PROCESSED.

Parameters:

invite_id (str) – The identifier of the invite.

Returns:

An InviteModel with the invite’s details.

Raises:
  • PineconeValueError – If invite_id is empty.

  • NotFoundError – If no such invite exists in the organization. A deleted invite reads back as not found rather than as a status value.

  • ApiError – If the API returns an error response.

Return type:

InviteModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> invite = admin.invites.describe(
...     invite_id="9c8e3528-b9c0-4358-84ce-84c28e91b566"
... )
list(*, limit=None, pagination_token=None)[source]

List the organization’s pending and expired invites, with lazy pagination.

Warning

This omits invites that have already been accepted. An invite missing from this list has not necessarily vanished — it may have been accepted, in which case describe() still returns it with status == InviteStatus.PROCESSED, and the accepted invitee is now a member reachable through admin.users. Don’t treat absence here as proof an invite never existed.

No request is sent until the returned paginator is iterated. Iterating past the first page reuses the cursor returned with the previous page; iteration stops once a page comes back without one.

Parameters:
  • limit (int | None) – Number of invites returned per page, between 1 and 100. It caps page size, not how many invites the paginator yields in total — the paginator keeps following cursors until the pages run out. Use itertools.islice() to cap the total. None lets the server choose the page size.

  • pagination_token (str | None) – Cursor to resume iteration from a prior call’s .pagination_token. Reuse it with the same limit.

Returns:

Paginator over InviteModel objects. Supports for loops, .to_list(), .pages() for page-level access, and .pagination_token for resumption.

Raises:
  • PineconeValueError – If limit is outside 1-100. Raised before any network call.

  • ApiError – If the API returns an error response.

Return type:

Paginator[InviteModel]

Examples

for invite in admin.invites.list():
    print(invite.id, invite.email, invite.status)

for page in admin.invites.list(limit=25).pages():
    print(len(page.items), page.pagination_token)
resend(*, invite_id)[source]

Resend an invite’s email and push its expiration back out.

Works on pending and expired invites alike: the returned invite is pending again with a fresh expires_at.

Warning

Invite emails are rate limited per organization. Past that limit this raises RateLimitError — don’t retry in a tight loop. Honor exc.retry_after when the server supplies one, and back off generously otherwise; the budget refills slowly enough that a sub-second retry will just fail again. An already-accepted invite raises ConflictError instead, which is never a signal to retry: there is nothing left to resend.

Parameters:

invite_id (str) – The identifier of the invite to resend.

Returns:

The updated InviteModel, with status back to pending and a later expires_at.

Raises:
  • PineconeValueError – If invite_id is empty.

  • NotFoundError – If no such invite exists in the organization.

  • ConflictError – If the invite has already been accepted and so cannot be resent.

  • RateLimitError – If the organization’s invite-email budget is exhausted. retry_after carries the server’s cooldown period when one is supplied.

  • ApiError – If the API returns an error response.

Return type:

InviteModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> invite = admin.invites.resend(
...     invite_id="9c8e3528-b9c0-4358-84ce-84c28e91b566"
... )

Service Accounts

The OAuth principals the Admin client itself authenticates as. create and rotate_secret are the only operations that return a client_secret, and each returns it exactly once — capture it or rotate again.

class pinecone.admin.service_accounts.ServiceAccounts(*, http)[source]

Bases: object

Control-plane operations for the organization’s service accounts.

A service account is a non-human, machine identity for programmatic API access — distinct from the human members that Users manages. It is also the OAuth principal that Admin itself authenticates as, so this namespace manages the same kind of credential the client is holding. Two consequences are worth knowing before calling anything here:

  • create() and rotate_secret() are the only operations that ever return a client_secret, and each returns it exactly once. Nothing can retrieve it afterwards.

  • rotate_secret() and delete() aimed at the account whose credentials built this client will break it. See those methods.

Role bindings are not part of a service account’s representation: create() can send initial ones, but no method here returns them. Use the role-binding operations with principal_type="service_account" and the account’s id as principal_id to read or change them afterwards.

Parameters:

http (HTTPClient) – HTTP client for making API requests.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for account in admin.service_accounts.list():
...     print(account.id, account.name)
__init__(*, http)[source]
Parameters:

http (HTTPClient)

Return type:

None

create(*, name, role_bindings=None)[source]

Create a service account and receive its OAuth secret, once.

Warning

The returned client_secret is shown exactly once. It is not stored by the SDK and no later request can retrieve it — not describe(), not list(). Capture it now or the only recovery is rotate_secret(), which mints a different one. Store it as a credential; repr() of the result masks it, but to_dict() and JSON encoding do not.

The server does not deduplicate on name: repeating this call creates another, separate service account with its own credentials.

Parameters:
  • name (str) – Human-readable label for the account. Sent verbatim — the SDK checks only that it is non-empty and leaves length and content to the server to validate. The server measures length in UTF-8 bytes rather than codepoints, so a name of multi-byte characters can be rejected while looking short to Python’s len().

  • role_bindings (Sequence[RoleBindingInput | Mapping[str, Any]] | None) – Optional initial roles, as RoleBindingInput instances or plain dicts, mixed freely. Each entry needs resource_type ("organization" or "project") and role; project scope additionally needs resource_id, the project UUID. None and [] both create an account with no roles at all — it can obtain a token but do nothing with it until roles are granted through the role-binding operations. The bindings are not echoed in the response.

Returns:

A ServiceAccountWithSecret exposing .service_account (the metadata, including the id and the OAuth client_id) and .client_secret.

Raises:
  • PineconeValueError – If name is empty, or if any role_bindings entry is missing resource_type/role, carries an unrecognized key, or names a value this SDK release does not know. The message names the index of the offending entry. Raised before any network call.

  • ForbiddenError – If the caller lacks permission to create service accounts, or the organization’s plan does not include them. The two cases are distinguishable only by the server’s message.

  • ApiError – If the API returns an error response.

Return type:

ServiceAccountWithSecret

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> created = admin.service_accounts.create(name="ci-prod")
>>> created.service_account.client_id
'l3Ow0CmFyc4jOONcwiKUCRqQKN0tiCAn'

With initial roles, typed or as dicts:

from pinecone.models.admin import ResourceType, RoleBindingInput, RoleName

created = admin.service_accounts.create(
    name="ci-prod",
    role_bindings=[
        RoleBindingInput(
            resource_type=ResourceType.PROJECT,
            role=RoleName.DATA_PLANE_EDITOR,
            resource_id="a2f7dddb-1597-4eff-9f71-535fde243f58",
        ),
        {"resource_type": "organization", "role": "OrgMember"},
    ],
)
store_secret(created.client_secret)
delete(*, service_account_id)[source]

Delete a service account, its role bindings, and its credentials.

Warning

Deleting the service account whose client_id/client_secret built this Admin client revokes the credentials the client authenticates with. Tokens it already minted stop working within seconds and no new one can be obtained.

The account and its role bindings are gone by the time this call returns; a repeat of this call raises NotFoundError, like any other reference to a deleted account.

Parameters:

service_account_id (str) – The identifier of the service account to delete.

Raises:
Return type:

None

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> admin.service_accounts.delete(
...     service_account_id="f8a3b2c1-4d5e-6f7a-8b9c-0d1e2f3a4b5c"
... )
describe(*, service_account_id)[source]

Get detailed information about one service account.

The client_secret is never part of this response — it exists in the clear only in the create() and rotate_secret() results.

Parameters:

service_account_id (str) – The identifier of the service account.

Returns:

A ServiceAccountModel with the account’s metadata.

Raises:
Return type:

ServiceAccountModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> account = admin.service_accounts.describe(
...     service_account_id="f8a3b2c1-4d5e-6f7a-8b9c-0d1e2f3a4b5c"
... )
list(*, limit=None, pagination_token=None)[source]

List the organization’s service accounts, with lazy pagination.

No request is sent until the returned paginator is iterated. Iterating past the first page reuses the cursor from the previous response’s pagination.next verbatim; iteration stops on the first page that comes back without one.

Parameters:
  • limit (int | None) – Number of service accounts the server returns per page, between 1 and 100. It caps each page, not how many accounts the paginator yields in total; the paginator keeps following cursors until the pages run out. Use itertools.islice() to cap the total. When None the parameter is omitted and the server chooses the page size.

  • pagination_token (str | None) – Cursor from a prior response’s pagination.next, to resume where a previous iteration stopped. Reuse it with the same limit.

Returns:

Paginator over ServiceAccountModel objects. Supports for loops, .to_list(), .pages() for page-level access, and .pagination_token for resumption. The listed accounts carry no client_secret — that is returned only by create() and rotate_secret().

Raises:
  • PineconeValueError – If limit is outside 1-100. Raised before any network call.

  • ApiError – If the API returns an error response.

Return type:

Paginator[ServiceAccountModel]

Examples

for account in admin.service_accounts.list():
    print(account.id, account.name, account.client_id)

for page in admin.service_accounts.list(limit=25).pages():
    print(len(page.items), page.pagination_token)
rotate_secret(*, service_account_id)[source]

Issue a new OAuth client secret for a service account, revoking the old one.

Warning

The new client_secret is shown exactly once, in this response. It is not stored by the SDK and no later request can retrieve it; a rotation whose result is dropped can only be recovered by rotating again. repr() of the result masks it, but to_dict() and JSON encoding do not — never log the raw value.

Warning

Rotating the secret of the service account whose credentials built this Admin client invalidates the secret that client holds. Its current access token keeps working until it expires, but the next token exchange fails until the client is rebuilt with the new secret. The previous secret and the tokens it minted are revoked within seconds.

The account’s id and OAuth client_id are unchanged: only the secret is new, so callers replace one value rather than reconfiguring the client identity. updated_at is not touched either — rotation leaves no trace in the account metadata, so do not use it to tell whether a rotation happened.

Parameters:

service_account_id (str) – The identifier of the service account whose secret should be rotated.

Returns:

A ServiceAccountWithSecret whose .client_secret is the newly issued secret and whose .service_account carries the unchanged id and client_id.

Raises:
  • PineconeValueError – If service_account_id is empty.

  • NotFoundError – If no such service account exists in the organization.

  • ForbiddenError – If the caller lacks the rotate permission, or the organization’s plan does not include service accounts.

  • ApiError – If the API returns an error response.

Return type:

ServiceAccountWithSecret

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> rotated = admin.service_accounts.rotate_secret(
...     service_account_id="f8a3b2c1-4d5e-6f7a-8b9c-0d1e2f3a4b5c"
... )
>>> store_secret(rotated.client_secret)
update(*, service_account_id, name=None)[source]

Rename a service account.

Only the name is mutable here. Roles are managed through the role-binding operations, and the OAuth client_id and client_secret are not editable at all — rotate the secret with rotate_secret() instead.

Parameters:
  • service_account_id (str) – The identifier of the service account.

  • name (str | None) – The new name. Sent verbatim; the server owns the length and content rules, and measures length in UTF-8 bytes rather than codepoints.

Returns:

The updated ServiceAccountModel, with a fresh updated_at. No secret is returned.

Raises:
  • PineconeValueError – If service_account_id is empty, or if no updatable field was given. The server accepts a fieldless patch as a no-op success that merely bumps updated_at, which hides a caller bug — usually a misspelled keyword — behind an apparent success, so the SDK names it instead. Raised before any network call.

  • NotFoundError – If no such service account exists in the organization.

  • ForbiddenError – If the caller lacks the update permission, or the organization’s plan does not include service accounts.

  • ApiError – If the API returns an error response.

Return type:

ServiceAccountModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> account = admin.service_accounts.update(
...     service_account_id="f8a3b2c1-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
...     name="ci-prod-renamed",
... )

Role Bindings

The whole of Pinecone’s authorization model: one role granted to one principal — user, service account, API key, or pending invite — at one scope, either the organization or a single project. Nothing else confers permissions, and bindings are immutable, so a role change is a create followed by a delete.

class pinecone.admin.role_bindings.RoleBindings(*, http)[source]

Bases: object

Control-plane operations for the organization’s role bindings.

A role binding is the whole of Pinecone’s authorization model: it grants one role to one principal — a user, service account, API key, or pending invite — at one scope, either the organization or a single project. Nothing else confers permissions, so this namespace is where a principal’s access is read and changed. The other admin namespaces deliberately do not carry role bindings in their models; list() with principal_type and principal_id is how a principal’s access is enumerated.

Bindings are immutable: there is no update. Changing a principal’s role means create() for the new one and delete() for the old one, in that order — deleting first can strip the principal’s last organization-membership binding, which the server refuses.

The server owns which role may be bound to which scope and principal type, and which roles an organization’s plan includes. Those rules vary by plan, so the SDK does not replicate them: it checks only that a value is one this release knows about and that the filter co-requirements hold, and lets the server’s own error messages — which name the role, the scope, and the plan — explain the rest.

Parameters:

http (HTTPClient) – HTTP client for making API requests.

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> for binding in admin.role_bindings.list():
...     print(binding.principal_id, binding.role, binding.resource_id)
__init__(*, http)[source]
Parameters:

http (HTTPClient)

Return type:

None

create(*, principal_type, principal_id, resource_type, role, resource_id=None)[source]

Grant a role to a principal at an organization or project scope.

The binding takes effect immediately and is returned with the id delete() needs — the only way to revoke it, since bindings cannot be edited in place.

The same scope-and-role pair is accepted as an initial binding by create() and create(), so a grant expressed once works in all three places.

Whether the grant is allowed is entirely the server’s call, and it refuses for several distinct reasons the SDK cannot tell apart in advance: a project-scoped binding must name a project-scoped role, an api_key principal accepts only the data/control-plane roles, some roles are gated behind the organization’s plan, and the caller cannot grant a permission it does not itself hold. Each rejection carries a message naming the role, the scope, and — for plan gating — the plan required, so read the error rather than pre-flighting the rules.

Parameters:
  • principal_type (str | PrincipalType) – The kind of principal receiving the role — "user", "service_account", "api_key", or "invite". Binding to an invite grants the role to whoever accepts it; once accepted the server refuses further bindings on the invite, and the roles must be managed on the resulting user instead.

  • principal_id (str) – The principal’s UUID. Sent verbatim — an unknown or unparseable principal is rejected by the server.

  • resource_type (str | ResourceType) – The scope — "organization" or "project".

  • role (str | RoleName) – The role to grant, spelled as the wire name ("DataPlaneEditor"). RoleName members are accepted interchangeably.

  • resource_id (str | None) – The project UUID. Required when resource_type is "project". For "organization" scope leave it unset — the organization is inferred from the credentials, and passing any organization other than the caller’s own is rejected.

Returns:

The created RoleBindingModel, whose resource_id is always populated: an organization-scoped binding comes back carrying the organization the credentials resolved to, even though the request omitted it.

Raises:
  • PineconeValueError – If principal_id is empty; if principal_type, resource_type, or role names a value this SDK release does not know; or if resource_type is "project" and resource_id is missing. Raised before any network call.

  • NotFoundError – If the principal or the resource does not exist in the caller’s organization.

  • ConflictError – If an identical binding already exists, or the principal is an invite that has already been accepted.

  • ForbiddenError – If the role cannot be bound to that scope or principal type, the organization’s plan does not include it, or the caller would be granting a permission it does not hold.

  • ApiError – If the API returns an error response.

Return type:

RoleBindingModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> binding = admin.role_bindings.create(
...     principal_type="user",
...     principal_id="e2e92523-85dc-4142-b8c2-e681be8b78df",
...     resource_type="organization",
...     role="OrgMember",
... )

A project-scoped grant, with enums:

from pinecone.models.admin import PrincipalType, ResourceType, RoleName

binding = admin.role_bindings.create(
    principal_type=PrincipalType.SERVICE_ACCOUNT,
    principal_id="f8a3b2c1-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    resource_type=ResourceType.PROJECT,
    resource_id="a2f7dddb-1597-4eff-9f71-535fde243f58",
    role=RoleName.DATA_PLANE_EDITOR,
)
delete(*, role_binding_id)[source]

Revoke a role binding, by the binding’s own ID.

Deletion is addressed by role_binding_id rather than by the principal/scope/role triple, so revoking a role means finding the binding first — usually with list() filtered by principal_type and principal_id, or from the create() result.

The permissions are revoked immediately, after which the binding reads back as not found — including for a repeat of this call, so delete is not idempotent in the “second call also succeeds” sense.

Some bindings cannot be deleted at all: the organization’s last OrgOwner, a user’s last organization-membership binding while they still hold other roles, and a pending invite’s last organization-membership binding (delete the invite instead). Organizations whose users are managed by an identity provider refuse user and invite binding changes outright.

Parameters:

role_binding_id (str) – The identifier of the role binding to delete.

Raises:
  • PineconeValueError – If role_binding_id is empty.

  • NotFoundError – If no such role binding is visible to the caller, including a repeat of a successful delete.

  • ConflictError – If deleting the binding would strip the organization of its last owner, remove a principal’s last organization membership, or the organization’s user management is delegated to an identity provider.

  • ApiError – If the API returns an error response.

Return type:

None

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> admin.role_bindings.delete(
...     role_binding_id="9a8e3528-b9c0-4358-84ce-84c28e91b566"
... )
describe(*, role_binding_id)[source]

Get detailed information about one role binding.

Parameters:

role_binding_id (str) – The identifier of the role binding.

Returns:

A RoleBindingModel with the principal, the scope, the role, and when it was granted.

Raises:
  • PineconeValueError – If role_binding_id is empty.

  • NotFoundError – If no such role binding is visible to the caller. A binding in another organization, and a project binding the caller cannot see, both look the same as one that does not exist — absence and inaccessibility are deliberately indistinguishable here.

  • ApiError – If the API returns an error response.

Return type:

RoleBindingModel

Examples

>>> from pinecone import Admin
>>> admin = Admin(client_id="your-client-id", client_secret="your-client-secret")
>>> binding = admin.role_bindings.describe(
...     role_binding_id="9a8e3528-b9c0-4358-84ce-84c28e91b566"
... )
list(*, principal_type=None, principal_id=None, resource_type=None, resource_id=None, role=None, limit=None, pagination_token=None)[source]

List the organization’s role bindings, with lazy pagination.

Every supplied filter is combined with AND, so list(principal_type="user", role="OrgOwner") returns the bindings that are both. With no filters at all it walks every binding the caller is allowed to see, which for an org owner is the organization’s entire authorization state.

No request is sent until the returned paginator is iterated. Iterating past the first page automatically follows the cursor from the page before it; iteration stops once a page comes back with no cursor to follow. The filters and limit are carried onto every later page, because the server requires a cursor to be replayed with the query context that produced it.

Parameters:
  • principal_type (str | PrincipalType | None) – Restrict to one kind of principal — "user", "service_account", "api_key", or "invite". Required whenever principal_id is given, since an ID alone is ambiguous across principal kinds. Omitted when None.

  • principal_id (str | None) – Restrict to one principal’s bindings — a UUID for every principal type. Requires principal_type. Sent verbatim; an unparseable value is rejected by the server. Omitted when None.

  • resource_type (str | ResourceType | None) – Restrict to one scope kind — "organization" or "project". Required whenever resource_id is given. Omitted when None.

  • resource_id (str | None) – Restrict to one organization or project. Requires resource_type. Omitted when None.

  • role (str | RoleName | None) – Restrict to one role, spelled as the wire name ("ProjectOwner", not "project_owner"). RoleName members are accepted interchangeably. Omitted when None.

  • limit (int | None) – Number of bindings the server returns per page. It caps each page, not how many bindings the paginator yields in total; the paginator keeps following cursors until the pages run out. Use itertools.islice() to cap the total. When None the parameter is omitted and the server chooses the page size.

  • pagination_token (str | None) – Cursor from a previous call’s paginator (its pagination_token property), to resume where that iteration stopped. Reuse it with the same filters and limit.

Returns:

Paginator over RoleBindingModel objects. Supports for loops, .to_list(), .pages() for page-level access, and .pagination_token for resumption.

Raises:
  • PineconeValueError – If principal_id is given without principal_type, or resource_id without resource_type; or if principal_type, resource_type, or role names a value this SDK release does not know. Raised before any network call.

  • ApiError – If the API returns an error response.

Return type:

Paginator[RoleBindingModel]

Examples

for binding in admin.role_bindings.list():
    print(binding.id, binding.principal_id, binding.role)

everything_one_service_account_can_do = admin.role_bindings.list(
    principal_type="service_account",
    principal_id="f8a3b2c1-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
).to_list()

project_owners = admin.role_bindings.list(
    resource_type="project",
    resource_id="a2f7dddb-1597-4eff-9f71-535fde243f58",
    role="ProjectOwner",
).to_list()

for page in admin.role_bindings.list(limit=25).pages():
    print(len(page.items), page.pagination_token)