Delegated policies

Updated

A delegated policy is a set of limits an administrator writes once. Every send under it is evaluated on the server from the quote and the document row. Nothing an agent writes is an input, so a prompt cannot move a limit.

The rules

Fields of policy.rules
FieldMeaning
allowed_destinationsexact E.164 numbers
allowed_country_prefixes+1, +44 and so on. At least one destination rule is required
allowed_sender_numbersnull allows any sender, including the pool
max_pages_per_job, max_amount_micro_per_jobper send
daily_max_jobs, daily_max_amount_microper UTC day
monthly_max_jobs, monthly_max_amount_microper UTC month
allowed_document_sourcesuploaded, rendered, or both
allowed_environmentslive, test
expires_atUTC, exact
agent_ids, key_idswho the policy binds. An agent's own policy_ids binds it too

Create one

Shell
curl -s $FFA/policies -H "Authorization: Bearer $FFA_KEY" \
  -H "Content-Type: application/json" -d '{
  "name": "orders desk",
  "purpose": "confirm purchase orders to known suppliers",
  "rules": {
    "allowed_country_prefixes": ["+1"],
    "max_pages_per_job": 10,
    "max_amount_micro_per_job": 500000,
    "daily_max_amount_micro": 5000000,
    "allowed_document_sources": ["rendered"],
    "allowed_environments": ["live"],
    "expires_at": "2027-01-01T00:00:00Z",
    "agent_ids": ["agent_..."]
  }
}'

Scope policy:admin, never on an agent key. PATCH makes version n+1. Every version is immutable and a job records the version that allowed it.

How is a send evaluated?

In this order, and the first failing rule decides. Enabled, applies to this key or agent, expiry, environment, destination, sender, pages, amount, document source, daily jobs, daily amount, monthly jobs, monthly amount. Caps count the planned send, so a daily cap of 3 allows the third and refuses the fourth. The counters are locked before the wallet, so two concurrent sends serialize on the cap.

Dry run

Shell
curl -s $FFA/policy-evaluations -H "Authorization: Bearer $FFA_KEY" \
  -H "Content-Type: application/json" -d '{"quote_id": "quote_..."}'

Allow or deny, with the first failing rule and every denial listed, executed: false. Through MCP the verdict rides on the quote: quote_fax answers with a policy object, the same evaluation the send runs. GET /v1/policies/effective tells an API key what it may do on its own and whether a person is needed for the rest.

Budgets

Separate from policies, a budget is a daily or monthly spending cap per organization, project or agent, per environment. The hold refuses budget_exceeded or agent_budget_exceeded before any money moves. Writing a budget needs billing:write, which an agent key is never issued.