Skip to main content

Overview

The grants client manages authorization grants — the records that track which users have authorized which agents with which scopes. Grants also support delegation, where a parent agent can create a sub-grant for a child agent. Access the grants client via client.grants.

Get

Retrieve a single grant by its ID:
from grantex import Grantex

with Grantex(api_key="gx_live_...") as client:
    grant = client.grants.get("grnt_abc123")

    print(f"Agent: {grant.agent_id}")
    print(f"Principal: {grant.principal_id}")
    print(f"Scopes: {grant.scopes}")
    print(f"Status: {grant.status}")
    print(f"Expires at: {grant.expires_at}")

List

List grants with optional filters:
from grantex import Grantex, ListGrantsParams

with Grantex(api_key="gx_live_...") as client:
    # List all grants
    result = client.grants.list()
    print(f"Total grants: {result.total}")

    # List with filters
    result = client.grants.list(ListGrantsParams(
        agent_id="agt_abc123",
        status="active",
        page=1,
        page_size=25,
    ))

    for grant in result.grants:
        print(f"  {grant.id}: {grant.scopes} ({grant.status})")

ListGrantsParams

FieldTypeRequiredDescription
agent_idstr | NoneNoFilter by agent ID.
principal_idstr | NoneNoFilter by principal (user) ID.
statusstr | NoneNoFilter by status ("active", "revoked", "expired").
pageint | NoneNoPage number for pagination.
page_sizeint | NoneNoNumber of results per page.

ListGrantsResponse

FieldTypeDescription
grantstuple[Grant, ...]The list of grants.
totalintTotal number of matching grants.
pageintCurrent page number.
page_sizeintNumber of grants per page.

Revoke

Revoke a grant by its ID. This immediately invalidates the grant and any tokens issued under it:
client.grants.revoke("grnt_abc123")
# Returns None on success

Delegate

Create a delegated sub-grant for a child agent. The sub-agent receives a subset of the parent grant’s scopes:
from grantex import Grantex

with Grantex(api_key="gx_live_...") as client:
    result = client.grants.delegate(
        parent_grant_token="eyJhbGciOiJSUzI1NiIs...",
        sub_agent_id="agt_sub_agent",
        scopes=["files:read"],
        expires_in="1h",
    )

    print(f"Delegated grant token: {result['grantToken']}")

Parameters

All parameters are keyword-only.
ParameterTypeRequiredDescription
parent_grant_tokenstrYesThe parent agent’s grant token (JWT).
sub_agent_idstrYesThe agent ID of the sub-agent receiving the delegation.
scopeslist[str]YesScopes to delegate (must be a subset of parent scopes).
expires_instr | NoneNoTTL for the delegated grant (e.g. "1h", "30m").

Verify

Verify a grant token online against the Grantex API. The SDK uses the server-verified claims returned by POST /v1/grants/verify — it does not decode the caller-supplied token locally, so forged or tampered tokens are always rejected by the server before any claim is surfaced. Raises GrantexTokenError if the server reports the token as inactive (revoked, expired, or unknown):
from grantex import Grantex

with Grantex(api_key="gx_live_...") as client:
    grant = client.grants.verify("eyJhbGciOiJSUzI1NiIs...")

    print(f"Token ID: {grant.token_id}")
    print(f"Grant ID: {grant.grant_id}")
    print(f"Principal: {grant.principal_id}")
    print(f"Agent DID: {grant.agent_did}")
    print(f"Scopes: {grant.scopes}")
Returns a VerifiedGrant dataclass. See Offline Verification for the full field reference.
For purely offline verification without any network call to the Grantex API, use the standalone verify_grant_token() function instead.

Grant Type

The Grant frozen dataclass has the following fields:
FieldTypeDescription
idstrUnique grant identifier.
agent_idstrThe agent ID.
agent_didstrThe agent’s DID.
principal_idstrThe user/principal who authorized the grant.
developer_idstrThe developer who owns the agent.
scopestuple[str, ...]The granted scopes.
statusstrGrant status ("active", "revoked", "expired").
issued_atstrISO 8601 timestamp when the grant was issued.
expires_atstrISO 8601 timestamp when the grant expires.
revoked_atstr | NoneISO 8601 timestamp when the grant was revoked (if applicable).

Example: Delegation Chain

from grantex import Grantex, AuthorizeParams, ExchangeTokenParams

with Grantex(api_key="gx_live_...") as client:
    # Parent agent gets a grant token
    auth = client.authorize(AuthorizeParams(
        agent_id="agt_parent",
        user_id="user_xyz",
        scopes=["files:read", "files:write", "calendar:read"],
    ))

    # ... user approves, code is exchanged for token ...
    # parent_token = client.tokens.exchange(...)

    # Delegate a subset of scopes to a sub-agent
    delegated = client.grants.delegate(
        parent_grant_token=parent_token,
        sub_agent_id="agt_child",
        scopes=["files:read"],  # subset of parent scopes
        expires_in="30m",
    )