Skip to content

Approval API Reference

Module functions

require_approval

require_approval(
    fn: Callable | None = None,
    *,
    action: str | None = None,
    requested_by: str | None = None,
    callback_url: str | None = None,
) -> Callable

Decorator that gates a function behind human approval.

Reads PRIMITIF_API_KEY from the environment. No client setup needed.

Can be used with or without parentheses: @require_approval or @require_approval(action="Deploy").

When the human approves, call approval.dispatch(event) in your webhook handler to execute the original function automatically.

Parameters:

Name Type Description Default
fn Callable | None

The function to wrap. Passed automatically when used as @require_approval without parentheses.

None
action str | None

Human-readable action name shown to the approver. Defaults to the function name with underscores replaced by spaces (send_invoice -> "Send invoice").

None
requested_by str | None

Optional agent or service identifier.

None
callback_url str | None

Optional webhook URL for direct callback.

None

Returns:

Type Description
Callable

The decorated function. Each call returns an ApprovalRequest

Callable

(status "pending"). The original is accessible via

Callable

wrapped.original.

Example::

from primitif.approval import require_approval

@require_approval
def deploy(service, branch):
    run_pipeline(service, branch)

req = deploy("api-gateway", "main")
print(req.approval_url)  # share with the human

# In your webhook handler:
from primitif import approval
approval.dispatch(event)  # runs deploy() with original args

create_request

create_request(
    action: str,
    *,
    context: dict[str, Any] | None = None,
    callback_url: str | None = None,
    requested_by: str | None = None,
) -> ApprovalRequest

Create an approval request. Returns immediately with a pending status.

Parameters:

Name Type Description Default
action str

Human-readable description of the action awaiting approval (e.g. "Send contract to Acme").

required
context dict[str, Any] | None

Arbitrary JSON dict passed to the approver and included in the webhook payload.

None
callback_url str | None

Optional URL for a direct webhook callback when the request is decided.

None
requested_by str | None

Optional agent or service identifier.

None
Example

from primitif import approval req = approval.create_request( ... "Send contract", ... context={"client": "Acme", "amount": 50000}, ... ) print(req.approval_url)

get_request

get_request(request_id: str) -> ApprovalRequest

Get the current status of an approval request.

Parameters:

Name Type Description Default
request_id str

The approval request ID.

required
Example

status = approval.get_request("apr_abc123") print(status.status)

list_requests

list_requests(
    *,
    status: Literal[
        "pending", "approved", "rejected", "expired"
    ]
    | None = None,
    limit: int = 20,
    cursor: str | None = None,
) -> PaginatedList[ApprovalRequest]

List approval requests, optionally filtered by status.

Parameters:

Name Type Description Default
status Literal['pending', 'approved', 'rejected', 'expired'] | None

Filter by status. Omit to list all.

None
limit int

Maximum number of requests per page. Defaults to 20.

20
cursor str | None

Pagination cursor from a previous response.

None
Example

for req in approval.list_requests(status="pending"): ... print(req.action, req.approval_url)

dispatch

dispatch(event: dict) -> Any

Execute the function registered for an approved webhook event.

Verify the event with verify_webhook() before calling this.

Parameters:

Name Type Description Default
event dict

The parsed webhook JSON body.

required

Returns:

Type Description
Any

The return value of the executed function, or None if the

Any

event status is not "approved".

Raises:

Type Description
ApprovalError

If no handler is registered for the action.

Example::

from primitif import approval, verify_webhook

@app.post("/webhook/approval")
def handle():
    event = verify_webhook(
        body=request.data,
        signature=request.headers["X-Webhook-Signature"],
        secret="whsec_...",
    )
    approval.dispatch(event)
    return "", 200

Models

ApprovalRequest

Bases: BaseModel