Skip to main content

Type-safe Python SDK for the Endor Labs REST API — resource facades, operational workflows, and optional agent-context bootstrap

Project description

Endor Labs SDK

Endor Labs

AURI by Endor Labs — agentic application security platform (CLI, API, MCP, Skills, Web UI)

AURI platform · Platform docs · Quick start

Python CI

Type-safe, resource-oriented Python client for the Endor Labs REST API. List, get, create, update, and delete resources (projects, findings, scan results, policies, namespaces, and the rest of the registry-backed resource set) with consistent patterns for filtering, pagination, namespace traversal, and IDE-friendly typed facades.

API stability: Core SDK surfaces (endorlabs.Client, resource facades, F() filters) are semver-stable. The endorlabs.workflows package holds operational CLIs and estate analytics helpers that may evolve faster than core facades — pin versions in production automation if you depend on workflow modules directly.

Start here

You want to… Go to
Use the SDK (API scripts, CI) InstallationQuick startno init() required
Bootstrap an AI agent (API + skills) Agent bootstrapdiscover() then init() for workflows
Try the SDK on a real tenant docs/guides/examples.md · Try it with skills
SDK contracts and deep reference docs/README.md
Contribute to this repo CONTRIBUTORS.md

Installation

pip install endorlabs

Or with uv:

uv add endorlabs

From the repository (editable):

git clone https://github.com/endorlabs/endorlabs-sdk.git
cd endorlabs-sdk
uv sync
# or: pip install -e .

Verify: uv run python -c "import endorlabs; print(endorlabs.__version__)"

Source repo: endorlabs/endorlabs-sdk — PyPI distribution name is endorlabs (import endorlabs).

Optional extras

Extra Install Enables
analytics pip install 'endorlabs[analytics]' DataFrame / Parquet export and estate graph metrics — see docs/estate/README.md

CSV export from workflows.estate.analyze.cardinality.tabular works without extras. In this repo: uv sync --extra analytics. Product docs: Docs MCP (or llms.txt without MCP).

Quick start

SDK-only — examples below do not call endorlabs.init(). For agent bootstrap, see AGENTS.md.

Credentials: Set env vars per Configuration (API key for CI). For local or agent sessions, probe with uv run endor-auth check or use skill endor-auth-setup (shipped after init()).

Entry point: endorlabs.Client(tenant=...). Resources are PascalCase facades (client.Project, client.Finding, …) matching endorctl api … --resource <Kind>.

Basic usage

import os
import endorlabs

client = endorlabs.Client(
    tenant=os.getenv("ENDOR_NAMESPACE", "your-tenant.namespace"),
    logging_level="ERROR",
)

namespaces = client.Namespace.list(traverse=True)
projects = client.Project.list(traverse=True, max_pages=1)

if projects:
    project = client.Project.get(projects[0].uuid)
    print(project.meta.name)

List field masks: a non-empty mask= on list() returns list[dict] wire JSON rows, not full Pydantic models. Omit mask when you need typed resources end-to-end. See docs/guides/consumer-ux-list-update.md.

Large estate lists: for project-scoped resources at scale, use endorlabs.tools.list_sharding or the endor-estate workflow CLI (see docs/contributing/list-query-performance.md).

Requesting a scan and waiting for results

repo_url = "https://github.com/org/example-repo.git"
projects = client.Project.search_by_name(repo_url, traverse=True, max_pages=2)
project = projects[0] if projects else None

client.Project.update(project, scan_state="SCAN_STATE_REQUEST_FULL_RESCAN")

client.wait_until(
    lambda: (
        (p := client.Project.get(project))
        and p.processing_status.scan_state == "SCAN_STATE_IDLE"
    ),
    timeout=300,
)

scans = client.ScanResult.list_by_project(project, limit=1)
latest_scan = scans[0] if scans else None
findings = client.Finding.list_for_context(latest_scan, max_pages=1) if latest_scan else None

Relationship accessors: list_by_project / list_for_context return list[T] like .list(). Stitch accessors (to_dependency_metadata, …) return RouteResult — use .value / .single and inspect .edge_used / .warnings. Prefer list accessors over hand-built filters when the edge exists in the contract. Catalog: docs/generated-reference/resource-routes.md · guide: docs/guides/facade-helpers.md.

Pagination on .list(): limit=N is an alias for page_size=N (same idea as list_by_project(..., limit=N)). Use max_pages to cap fetch depth.

More patterns (filters, F(), masks, namespace scoping): docs/guides/consumer-ux-list-update.md, docs/guides/retrieving-scan-results.md.

Transport-only APIClient

from endorlabs import APIClient

client = APIClient()
response = client.get("v1/namespaces/tenant.namespace/projects")

Prefer endorlabs.Client for typed models and namespace handling.

Configuration

The SDK uses environment variables only (no config file loading). Precedence: constructor arguments → environment variables → built-in defaults.

Variable Purpose
ENDOR_API API base URL (default: https://api.endorlabs.com)
ENDOR_API_CREDENTIALS_KEY API key
ENDOR_API_CREDENTIALS_SECRET API secret
ENDOR_TOKEN Bearer token (read at process start; Client never writes it)
ENDOR_NAMESPACE Default tenant namespace; API scope (SSO tenant root when method is sso)
ENDOR_LOG_LEVEL Optional: DEBUG, INFO, WARNING, ERROR, CRITICAL
ENDOR_MAX_RETRIES Optional: retry count (default: 5)
ENDOR_REQUEST_TIMEOUT Optional: HTTP read timeout in seconds (default: 60)
ENDOR_API_TIMEOUT Optional: endorctl-compatible timeout when request timeout unset
ENDOR_CREATE_TIMEOUT Optional: override timeout for create() POST requests

Canonical naming is tenant.namespace.child; do not use UUIDs in namespace paths. Full semantics: docs/contracts.md.

Example .env for local runs — use one credential mode (not both):

# Option A — bearer token (common for agent sessions)
ENDOR_TOKEN=your-bearer-token
ENDOR_NAMESPACE=your-tenant.namespace
ENDOR_LOG_LEVEL=INFO
# Option B — API key (CI)
ENDOR_API_CREDENTIALS_KEY=your-api-key
ENDOR_API_CREDENTIALS_SECRET=your-api-secret
ENDOR_NAMESPACE=your-tenant.namespace
ENDOR_LOG_LEVEL=INFO

If both token and API key variables are set, the SDK prefers the token; MCP and endorctl typically fail with conflicting auth.

Bearer sessions are in-memory only: load ENDOR_TOKEN once (or token= on Client), get a one-time stderr warning within 30 minutes of expiry, then fail closed on expiry/401 with an endor-auth refresh hint. Cross-session: uv run endor-auth refresh only — Client never writes secrets to disk or os.environ. Contract: agent-knowledge/contracts/errors-and-auth.md.

Agent bootstrap: discover() vs init()

Need Approach
INDEX, contracts, traps, stub path — no cwd writes print(endorlabs.discover()) or python -m endorlabs.examples.agent_bootstrap --dry-run — then read every bootstrap_paths entry
Skill playbooks on disk (call graph, scan RCA, bundles) endorlabs.init().endorlabs-context/sdk/skills/<id>/SKILL.md
Platform OpenAPI init(include_openapi=True) (auth required). Product docs: Docs MCP (or llms.txt)

Runnable probe (paths only): python -m endorlabs.examples.agent_bootstrap --dry-run. Shipped consumer guide: discover().agents_guide.

Call graphs (agents): CallGraphData.fetch() returns the raw envelope only. For search and path queries, read skill endor-fetch-and-search-call-graph after init() (or from the wheel: skills/endor-fetch-and-search-call-graph/SKILL.md via agent_knowledge_manifest()). Prefer endorlabs.workflows.callgraph.resolve_package_version_with_callgraph() and CallGraphData.decode()spec.call_graph_available does not guarantee stored graph data. Pass namespace=project.tenant_meta.namespace on PV lists and decode.

AI agents

Before Client(), run print(endorlabs.discover()) (or agent_bootstrap --dry-run) and read every path in bootstrap_paths. Before workflow tasks (call graph, project bundle, scan RCA), run endorlabs.init() and open the relevant skill under .endorlabs-context/sdk/skills/.

Browser auth, SSO setup, and skill walkthroughs: docs/guides/examples.md. Credential probe and refresh: uv run endor-auth check / endor-auth refresh (skill endor-auth-setup).

Try it with skills

Guided tenant sessions use shipped agent skills — start with docs/guides/examples.md. Wheel entry: print(endorlabs.discover()) or agent_bootstrap --dry-run; materialize with init() to .endorlabs-context/sdk/.

Further reading

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

endorlabs-0.6.0.tar.gz (730.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

endorlabs-0.6.0-py3-none-any.whl (1.1 MB view details)

Uploaded Python 3

File details

Details for the file endorlabs-0.6.0.tar.gz.

File metadata

  • Download URL: endorlabs-0.6.0.tar.gz
  • Upload date:
  • Size: 730.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for endorlabs-0.6.0.tar.gz
Algorithm Hash digest
SHA256 383214127fe55be1bc2dbac203343723341b94bf9ab4b118f0bb8218913eb676
MD5 3c428a55d8a1b24117b4015a9f9ab356
BLAKE2b-256 5532f67c346dd6d427f573b5a04353a7fe337a2f4679cb5c5a2f0f79d9f69158

See more details on using hashes here.

Provenance

The following attestation bundles were made for endorlabs-0.6.0.tar.gz:

Publisher: release-tag-publish.yml on endorlabs/endorlabs-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file endorlabs-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: endorlabs-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for endorlabs-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0fd3e5c69e1c9f554fc51a2745a94f15cdb24fd6a80e83f30159d476b7d47101
MD5 65508ab873d28d3b505290220c03c701
BLAKE2b-256 c44372cb391ebf948654720384cd027f759c6bb8a36e2b4d53d7def905122758

See more details on using hashes here.

Provenance

The following attestation bundles were made for endorlabs-0.6.0-py3-none-any.whl:

Publisher: release-tag-publish.yml on endorlabs/endorlabs-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page