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.

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
docs pip install 'endorlabs[docs]' User-docs sync (include_user_docs=True); OpenAPI download works on the base install
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 docs --extra analytics.

Quick start

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

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/tgowan-endor/BenchmarkJava.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; validated first when set
ENDOR_NAMESPACE Default tenant namespace (e.g. tenant.namespace)
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.

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 / user docs offline pip install 'endorlabs[docs]' then init(include_openapi=True, include_user_docs=True)

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.

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.5.0.tar.gz (2.0 MB view details)

Uploaded Source

Built Distribution

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

endorlabs-0.5.0-py3-none-any.whl (1.2 MB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for endorlabs-0.5.0.tar.gz
Algorithm Hash digest
SHA256 622fc8bef1c68278f79dbd006d10de0dc735501561e96562f559b3fa79a5b124
MD5 51548795f0a66b12bc5692f9a4a3667c
BLAKE2b-256 b140399c351dd4d10f2279de85cb5471241822856b99fbe6166ddd05cc3711fc

See more details on using hashes here.

Provenance

The following attestation bundles were made for endorlabs-0.5.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.5.0-py3-none-any.whl.

File metadata

  • Download URL: endorlabs-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 1.2 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.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 26fc4de1629dffca17ee764c1ba87514bcf7d0c2aafe4697e682b4804dc78951
MD5 9ccd0745d008b8e26de58ff55b6ffed7
BLAKE2b-256 c0009376ec23ddaf9014269b750ba208fed716449810f10d4a735b5d5788eade

See more details on using hashes here.

Provenance

The following attestation bundles were made for endorlabs-0.5.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