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.2 (latest) 1.7.1158 changelog
0.7.1 1.7.1133 changelog
main (unreleased) 1.7.1133 Integration branch; targets 0.8.0 — 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.2

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.2
File Size Uploaded
endorlabs-0.7.2.tar.gz 1.1 MB Details

Built distribution (wheel)

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

Total release size: 2.6 MB

Release files / endorlabs-0.7.2.tar.gz

Download URL endorlabs-0.7.2.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
c43b4239ca2d54f901551ac65df2721e07321d143b2f8b7e9aa788199323a97c
BLAKE2b-256 checksum
How to use checksums
e7ea5cdd877a901a8e0a5dcce48fd147774a0f9d95b1f9d715380322c80f9d6d
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 Sep 19, 2026.

Transparency log

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

Download URL endorlabs-0.7.2-py3-none-any.whl
Size 1.5 MB
Tags Python 3
SHA-256 checksum
How to use checksums
bc28042fbb0b4244319906ee6d499f8ed86a65bf922629f52fedd3faef1d0d08
BLAKE2b-256 checksum
How to use checksums
4105a9149b55cbaa458548c0025de864a60a73271415d86139f2e0c46fd590bd
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 Sep 19, 2026.

Transparency log

Release history Release notifications | RSS feed

0.7.4

2 release files

0.7.3

2 release files

This release

0.7.2 This release

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