Skip to main content

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.

Version compatibility

The SDK wheel version (endorlabs) is independent of endorctl semver. Each release documents the OpenAPI watermark it was built and tested against (see changelog and the provenance header in src/endorlabs/generated/registry_contract.py).

PyPI endorlabs OpenAPI watermark (endorctl) Notes
0.7.4 (latest) 1.7.1184 changelog
0.7.3 1.7.1174 changelog
0.7.2 1.7.1158 changelog
0.7.1 1.7.1133 changelog
main (unreleased) 1.7.1184 Integration branch — not on PyPI yet

Refresh model-sync before publishing when live API has moved: uv run python devtools/codegen/model_sync.py --verify-upstream-only. Automated bot PRs: model-sync-dispatch workflow.

Start here

You want to… Go to
Use the SDK (API scripts, CI) Installation → Quick start — no init() required
Bootstrap an AI agent (API + skills) Agent bootstrap — discover() then init() for workflows
Try the SDK on a real tenant docs/guides/examples.md · Try it with skills
Tenant executive HTML reports endor-reports build (or bare -n) — guide · reports README
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/_cache/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/_cache/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/_cache/sdk/.

Further reading

License

MIT. See LICENSE.

Metadata

Release files for endorlabs 0.7.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for endorlabs 0.7.4
File Size Uploaded
endorlabs-0.7.4.tar.gz 1.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for endorlabs 0.7.4
File Interpreter ABI Platform
endorlabs-0.7.4-py3-none-any.whl Python 3 none any Details

Total release size: 2.8 MB

Release files / endorlabs-0.7.4.tar.gz

Download URL endorlabs-0.7.4.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
3804cc525127fed31752db9201adeef6208c088551d22d5cceb810bc732c6ee5
BLAKE2b-256 checksum
How to use checksums
b23ced6458aff239d73a56213c850ea571c5ec3ad6ab6d7bf5a9c71cfc2d190d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / endorlabs-0.7.4-py3-none-any.whl

Download URL endorlabs-0.7.4-py3-none-any.whl
Size 1.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
160791e57c174ebf7bf7d0161dd0aba29d42baf06ac0bb5ad826205a7bcc842e
BLAKE2b-256 checksum
How to use checksums
97fa11f631c114117c07873f67deb98bb9b014cd4b4d8949028e62168050f8ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.4 This release

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.4

2 release files

0.5.3

1 release file

0.5.2

1 release file

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page