Download OpenAPI specification:
Paidwen controls what AI agents do. Before each action, the SDK asks the decision endpoint whether the agent may act, then applies the verdict. The agent keeps its own tool keys and performs the action itself. The agent proves its identity with its key, or with an agent token that the SDK obtains by exchanging the token its platform signed, under a trust rule of the organization. When the verdict waits for a human answer, the SDK polls the approval until the answer comes. The SDK sends its spans to the journal. The Paidwen command asks the same question from the hook of a coding agent, and signs in a developer with the device authorization grant. The admin endpoints declare the agents of an organization, their keys, their permissions, their budgets, the rules and the approval groups of the organization, answer the approvals, respond to incidents, read the journal and the audit, and manage the people, the plan and the settings of the organization. A script calls them with an admin key. The dashboard calls them with the session of a signed-in person and names the organization in the Paidwen-Organization header.
The question an agent asks before each action, and the wait for a human answer. The decision point serves them.
The agent is identified by its key. The service evaluates the permissions of the agent, its budget, then the rules of its organization, and answers with one of five verdicts. When the permissions or the budget refuse the action, they count as block. The most strict verdict wins. Rules in observation answer in the observed list and never change the verdict. Without any permission targeting the agent, without a spent budget and without any active rule that answers, the verdict is allow. Sending the same action identifier again within 24 hours returns the same decision. A verdict that waits for a human answer carries an approval to poll.
| action_id required | string <uuid> The identifier of the action, created by the SDK. Sending the same identifier again asks about the same action. |
required | object (Tool) |
object The parameters the agent passes to the tool. | |
object (Cost) | |
object (ActionContext) |
| Idempotent-Replayed | string Value: "true" Present with the value true when the decision was given before for the same action identifier. |
| action_id required | string <uuid> |
| agent_id | string The agent that the key or the token identifies. The SDK passes it to the agents it calls, as their caller. |
| verdict required | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" The answer to the agent. From the least to the most strict: allow, require_approval, escalate, block, quarantine. |
| rule_id required | string or null The active rule that decided, or null when no active rule decided. |
| rule_name | string The name of the active rule that decided, as the organization wrote it, present when this rule has a name. The Paidwen command gives it to the coding agent as the reason of a refusal. |
required | Array of objects (ObservedRule) The rules in observation that answered. They never change the verdict. |
object (PermissionOutcome) How the permissions of the agent answered. When allowed is false, the permissions count as block. The tool and server patterns name the entry that decided; they are absent when no entry lists the tool. | |
object (BudgetOutcome) The budget of the agent refused the action, and counts as block. The spent amount had reached the limit, or the spent amount and the estimated cost would exceed it. | |
object (Approval) The wait for a human answer. The SDK polls for the answer every interval seconds, until the answer comes or the wait expires. | |
object (IncidentReference) | |
| decided_at required | string <date-time> |
{- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "tool": {
- "name": "string",
- "kind": "function",
- "server": "string"
}, - "params": { },
- "cost": {
- "estimated_usd": 0
}, - "context": {
- "session_id": "string",
- "trace_id": "string",
- "parent_action_id": "7867ec4b-7e19-431d-9a91-62914a65d62b",
- "caller_agent_id": "string"
}
}{- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "agent_id": "string",
- "verdict": "allow",
- "rule_id": "string",
- "rule_name": "string",
- "observed": [
- {
- "rule_id": "string",
- "verdict": "allow"
}
], - "permission": {
- "allowed": true,
- "tool": "string",
- "server": "string"
}, - "budget": {
- "exceeded": "daily",
- "spent_usd": 0,
- "limit_usd": 0
}, - "approval": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "expires_in": 1,
- "interval": 1,
- "on_expiry": "deny"
}, - "incident": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "quarantine"
}, - "decided_at": "2019-08-24T14:15:22Z"
}The agent polls its own approval every interval seconds until the status is no longer pending. A poll that arrives less than interval seconds after the previous one receives 429 slow-down, and the agent then adds 5 seconds to its interval for all subsequent polls. An approval of another agent answers 404.
| approval_id required | string <uuid> |
| id required | string <uuid> |
| action_id required | string <uuid> |
| status required | string (ApprovalState) Enum: "pending" "approved" "denied" "expired" The state of an approval. pending waits for a human answer, approved and denied carry the answer, expired means no answer came before the deadline. They follow authorization_pending, the issued token, access_denied and expired_token of OpenID CIBA. |
| expires_at required | string <date-time> |
| interval required | integer <int32> >= 1 Seconds to wait between two polls. |
| on_expiry required | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "status": "pending",
- "expires_at": "2019-08-24T14:15:22Z",
- "interval": 1,
- "on_expiry": "deny"
}The spans the SDK sends to the journal, in the OTLP format of OpenTelemetry. The decision point serves them.
The body is an ExportTraceServiceRequest of OTLP, in binary protobuf or in JSON. The service keeps the spans of the Paidwen SDK and the calls to a model described by the OpenTelemetry semantic conventions for generative AI, and rejects the other spans through the partial success of OTLP. It writes the organization, the agent and the retention of the journal on each span from the agent key, and never trusts these attributes from the client.
The metrics the client of an agent sends, in the OTLP format of OpenTelemetry. The decision point counts the spending they carry in US dollars.
The body is an ExportMetricsServiceRequest of OTLP, in binary protobuf or in JSON. The service keeps every data point of a monotonic sum with delta temporality whose unit is USD, whatever the name of the metric: each point adds its value to the budget of the agent once, and becomes a cost line of the journal, with the session read from the session.id attribute of the point. A point sent again adds nothing. The service rejects every other data point through the partial success of OTLP. It writes the organization, the agent and the retention of the journal on each line from the agent key, and never trusts these attributes from the client.
The Paidwen command reads it to show who it acts as, and to check a key right after the sign-in. A disabled or quarantined agent still reads itself, with its status.
| id required | string <uuid> |
| name required | string |
| organization_id required | string <uuid> |
| environment required | string (Environment) Enum: "production" "test" |
| status required | string (AgentStatus) Enum: "active" "quarantined" "disabled" active answers as usual. quarantined answers quarantine to every decision, and the journal still records them. disabled refuses every request of the agent with 403. |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
- "environment": "production",
- "status": "active"
}| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (Agent) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "owner": "string",
- "team": "string",
- "description": "string",
- "model_provider": "string",
- "environment": "production",
- "risk_level": "low",
- "labels": {
- "property1": "string",
- "property2": "string"
}, - "budget": {
- "daily_usd": 1,
- "monthly_usd": 1
}, - "record_content": true,
- "status": "active",
- "spent": {
- "today_usd": 0,
- "month_usd": 0
}, - "risk": {
- "level": "low",
- "computed_at": "2019-08-24T14:15:22Z",
- "reasons": [
- {
- "code": "string",
- "level": "low",
- "text": "string"
}
]
}, - "trust_rule_id": "bc0189b6-423c-45bc-a15f-d23762319a0c",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}| name required | string [ 1 .. 128 ] characters |
| owner | string <email> <= 254 characters The email of a member of the organization, who answers for the agent. |
| team | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| description | string <= 2000 characters |
| model_provider | string [ 1 .. 128 ] characters |
| environment required | string (Environment) Enum: "production" "test" |
| risk_level | string (RiskLevel) Enum: "low" "medium" "high" "critical" |
object (Labels) <= 64 properties | |
object (Budget) The limits of the agent per calendar day and per calendar month, in UTC. At a limit, the agent receives block until the next window. | |
| record_content | boolean Default: true |
| Location | string The address of the agent. |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters The identity of the agent, unique in the organization, for example agent-support-prod. |
| owner | string [ 1 .. 256 ] characters The email of the member of the organization who answers for the agent. |
| team | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| description | string <= 2000 characters |
| model_provider | string [ 1 .. 128 ] characters |
| environment required | string (Environment) Enum: "production" "test" |
| risk_level | string (RiskLevel) Enum: "low" "medium" "high" "critical" |
required | object (Labels) <= 64 properties |
object (Budget) The limits of the agent per calendar day and per calendar month, in UTC. At a limit, the agent receives block until the next window. | |
| record_content required | boolean Whether the journal keeps the content of the exchanges of the agent: the instructions, the messages and the parameters of the tools. |
| status required | string (AgentStatus) Enum: "active" "quarantined" "disabled" active answers as usual. quarantined answers quarantine to every decision, and the journal still records them. disabled refuses every request of the agent with 403. |
object (AgentSpent) What the agent spent today and this month, in US dollars, as its budget counts it. | |
object (AgentRisk) The risk level that Paidwen computes from the permissions and the behavior of the agent, every 5 minutes. The level is the highest level of its reasons, and never lower than the declared risk_level. | |
| trust_rule_id | string <uuid> The trust rule that gives the agent its identity, when the agent proves it with the tokens of its platform. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "name": "string",
- "team": "string",
- "description": "string",
- "model_provider": "string",
- "environment": "production",
- "risk_level": "low",
- "labels": {
- "property1": "string",
- "property2": "string"
}, - "budget": {
- "daily_usd": 1,
- "monthly_usd": 1
}, - "record_content": true
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "owner": "string",
- "team": "string",
- "description": "string",
- "model_provider": "string",
- "environment": "production",
- "risk_level": "low",
- "labels": {
- "property1": "string",
- "property2": "string"
}, - "budget": {
- "daily_usd": 1,
- "monthly_usd": 1
}, - "record_content": true,
- "status": "active",
- "spent": {
- "today_usd": 0,
- "month_usd": 0
}, - "risk": {
- "level": "low",
- "computed_at": "2019-08-24T14:15:22Z",
- "reasons": [
- {
- "code": "string",
- "level": "low",
- "text": "string"
}
]
}, - "trust_rule_id": "bc0189b6-423c-45bc-a15f-d23762319a0c",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| agent_id required | string <uuid> |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters The identity of the agent, unique in the organization, for example agent-support-prod. |
| owner | string [ 1 .. 256 ] characters The email of the member of the organization who answers for the agent. |
| team | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| description | string <= 2000 characters |
| model_provider | string [ 1 .. 128 ] characters |
| environment required | string (Environment) Enum: "production" "test" |
| risk_level | string (RiskLevel) Enum: "low" "medium" "high" "critical" |
required | object (Labels) <= 64 properties |
object (Budget) The limits of the agent per calendar day and per calendar month, in UTC. At a limit, the agent receives block until the next window. | |
| record_content required | boolean Whether the journal keeps the content of the exchanges of the agent: the instructions, the messages and the parameters of the tools. |
| status required | string (AgentStatus) Enum: "active" "quarantined" "disabled" active answers as usual. quarantined answers quarantine to every decision, and the journal still records them. disabled refuses every request of the agent with 403. |
object (AgentSpent) What the agent spent today and this month, in US dollars, as its budget counts it. | |
object (AgentRisk) The risk level that Paidwen computes from the permissions and the behavior of the agent, every 5 minutes. The level is the highest level of its reasons, and never lower than the declared risk_level. | |
| trust_rule_id | string <uuid> The trust rule that gives the agent its identity, when the agent proves it with the tokens of its platform. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "owner": "string",
- "team": "string",
- "description": "string",
- "model_provider": "string",
- "environment": "production",
- "risk_level": "low",
- "labels": {
- "property1": "string",
- "property2": "string"
}, - "budget": {
- "daily_usd": 1,
- "monthly_usd": 1
}, - "record_content": true,
- "status": "active",
- "spent": {
- "today_usd": 0,
- "month_usd": 0
}, - "risk": {
- "level": "low",
- "computed_at": "2019-08-24T14:15:22Z",
- "reasons": [
- {
- "code": "string",
- "level": "low",
- "text": "string"
}
]
}, - "trust_rule_id": "bc0189b6-423c-45bc-a15f-d23762319a0c",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}An absent field does not change. A field set to null is removed. The environment of an agent never changes.
| agent_id required | string <uuid> |
| name | string [ 1 .. 128 ] characters |
| owner | string or null <email> <= 254 characters The email of a member of the organization, who answers for the agent. |
| team | string or null <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team of the organization. |
| description | string or null <= 2000 characters |
| model_provider | string or null [ 1 .. 128 ] characters |
| risk_level | string or null Enum: "low" "medium" "high" "critical" |
object or null The labels to set. A label set to null is removed. Null in place of the object removes every label. | |
object or null (BudgetPatch) The limits to set. A limit set to null is removed. Null in place of the object removes the budget. | |
| record_content | boolean |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters The identity of the agent, unique in the organization, for example agent-support-prod. |
| owner | string [ 1 .. 256 ] characters The email of the member of the organization who answers for the agent. |
| team | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| description | string <= 2000 characters |
| model_provider | string [ 1 .. 128 ] characters |
| environment required | string (Environment) Enum: "production" "test" |
| risk_level | string (RiskLevel) Enum: "low" "medium" "high" "critical" |
required | object (Labels) <= 64 properties |
object (Budget) The limits of the agent per calendar day and per calendar month, in UTC. At a limit, the agent receives block until the next window. | |
| record_content required | boolean Whether the journal keeps the content of the exchanges of the agent: the instructions, the messages and the parameters of the tools. |
| status required | string (AgentStatus) Enum: "active" "quarantined" "disabled" active answers as usual. quarantined answers quarantine to every decision, and the journal still records them. disabled refuses every request of the agent with 403. |
object (AgentSpent) What the agent spent today and this month, in US dollars, as its budget counts it. | |
object (AgentRisk) The risk level that Paidwen computes from the permissions and the behavior of the agent, every 5 minutes. The level is the highest level of its reasons, and never lower than the declared risk_level. | |
| trust_rule_id | string <uuid> The trust rule that gives the agent its identity, when the agent proves it with the tokens of its platform. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "name": "string",
- "team": "string",
- "description": "string",
- "model_provider": "string",
- "risk_level": "low",
- "labels": {
- "property1": "string",
- "property2": "string"
}, - "budget": {
- "daily_usd": 1,
- "monthly_usd": 1
}, - "record_content": true
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "owner": "string",
- "team": "string",
- "description": "string",
- "model_provider": "string",
- "environment": "production",
- "risk_level": "low",
- "labels": {
- "property1": "string",
- "property2": "string"
}, - "budget": {
- "daily_usd": 1,
- "monthly_usd": 1
}, - "record_content": true,
- "status": "active",
- "spent": {
- "today_usd": 0,
- "month_usd": 0
}, - "risk": {
- "level": "low",
- "computed_at": "2019-08-24T14:15:22Z",
- "reasons": [
- {
- "code": "string",
- "level": "low",
- "text": "string"
}
]
}, - "trust_rule_id": "bc0189b6-423c-45bc-a15f-d23762319a0c",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| agent_id required | string <uuid> |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of the last team of the previous page. |
required | Array of objects (Team) |
| has_more required | boolean |
{- "data": [
- {
- "handle": "string",
- "name": "string",
- "agents": 0,
- "created_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}| handle required | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| name required | string [ 1 .. 128 ] characters |
| Location | string The address of the team. |
| handle required | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| name required | string [ 1 .. 128 ] characters The name of the team as people read it, unique in the organization whatever the case. |
| agents required | integer <int32> >= 0 The number of agents of the team. |
| created_at required | string <date-time> |
{- "handle": "string",
- "name": "string"
}{- "handle": "string",
- "name": "string",
- "agents": 0,
- "created_at": "2019-08-24T14:15:22Z"
}| handle required | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| handle required | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| name required | string [ 1 .. 128 ] characters The name of the team as people read it, unique in the organization whatever the case. |
| agents required | integer <int32> >= 0 The number of agents of the team. |
| created_at required | string <date-time> |
{- "handle": "string",
- "name": "string",
- "agents": 0,
- "created_at": "2019-08-24T14:15:22Z"
}| handle required | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| name | string [ 1 .. 128 ] characters |
| handle required | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| name required | string [ 1 .. 128 ] characters The name of the team as people read it, unique in the organization whatever the case. |
| agents required | integer <int32> >= 0 The number of agents of the team. |
| created_at required | string <date-time> |
{- "name": "string"
}{- "handle": "string",
- "name": "string",
- "agents": 0,
- "created_at": "2019-08-24T14:15:22Z"
}| handle required | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}| agent_id required | string <uuid> |
| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (AgentKey) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
- "redacted": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}The response carries the key once, in secret. An agent holds at most two active keys, so that it changes its key without downtime: create the new key, deploy it, then revoke the old one.
| agent_id required | string <uuid> |
| id required | string <uuid> |
| agent_id required | string <uuid> |
| redacted required | string |
| created_at required | string <date-time> |
| revoked_at required | string or null <date-time> |
| secret required | string <password> The key itself, shown only in this response. |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
- "redacted": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z",
- "secret": "pa$$word"
}The key stops working within one second. Revoking a revoked key succeeds again.
| agent_id required | string <uuid> |
| key_id required | string <uuid> |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}The trust rules of the organization, which turn the tokens a platform signs into agents. The admin API serves them.
| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (TrustRule) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "issuer": "string",
- "jwks": {
- "keys": [
- {
- "kty": "RSA"
}
]
}, - "condition": "string",
- "agent_name": "string",
- "environment": "production",
- "team": "string",
- "owner": "string",
- "enabled": true,
- "agents": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}The service compiles the condition and the agent name with CEL before writing them. A condition that does not return a boolean, or a name that does not return a string, receives 400 with the error of CEL.
| name required | string [ 1 .. 128 ] characters |
| issuer required | string (TrustRuleIssuer) <= 512 characters ^https://[^\s]+$ The issuer the rule trusts, compared exactly with the iss claim of the token, for example https://token.actions.githubusercontent.com. |
object (JsonWebKeySet) The public keys of an issuer, in the JSON Web Key Set format of RFC 7517. | |
| condition required | string (TrustRuleCondition) [ 1 .. 4096 ] characters A CEL condition on the claims variable, the content of the token. The rule accepts a token when the condition returns true, for example claims.repository == "acme/billing-agent". |
| agent_name required | string (TrustRuleAgentName) [ 1 .. 4096 ] characters A CEL expression on the claims variable that returns the name of the agent, from 1 to 128 characters, for example claims.repository. |
| environment required | string (Environment) Enum: "production" "test" |
| team | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| owner | string <email> <= 254 characters The email of a member of the organization, who answers for the agents of the rule. |
| enabled | boolean Default: true |
| Location | string The address of the trust rule. |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters |
| issuer required | string (TrustRuleIssuer) <= 512 characters ^https://[^\s]+$ The issuer the rule trusts, compared exactly with the iss claim of the token, for example https://token.actions.githubusercontent.com. |
object (JsonWebKeySet) The public keys of an issuer, in the JSON Web Key Set format of RFC 7517. | |
| condition required | string (TrustRuleCondition) [ 1 .. 4096 ] characters A CEL condition on the claims variable, the content of the token. The rule accepts a token when the condition returns true, for example claims.repository == "acme/billing-agent". |
| agent_name required | string (TrustRuleAgentName) [ 1 .. 4096 ] characters A CEL expression on the claims variable that returns the name of the agent, from 1 to 128 characters, for example claims.repository. |
| environment required | string (Environment) Enum: "production" "test" |
| team | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| owner | string [ 1 .. 256 ] characters The email of the member who answers for the agents of the rule. |
| enabled required | boolean Whether the rule accepts tokens. A disabled rule refuses every exchange, and its agents no longer pass the decision point. |
| agents required | integer <int32> >= 0 The number of agents of the rule. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "name": "string",
- "issuer": "string",
- "jwks": {
- "keys": [
- {
- "kty": "RSA"
}
]
}, - "condition": "string",
- "agent_name": "string",
- "environment": "production",
- "team": "string",
- "enabled": true
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "issuer": "string",
- "jwks": {
- "keys": [
- {
- "kty": "RSA"
}
]
}, - "condition": "string",
- "agent_name": "string",
- "environment": "production",
- "team": "string",
- "owner": "string",
- "enabled": true,
- "agents": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| trust_rule_id required | string <uuid> |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters |
| issuer required | string (TrustRuleIssuer) <= 512 characters ^https://[^\s]+$ The issuer the rule trusts, compared exactly with the iss claim of the token, for example https://token.actions.githubusercontent.com. |
object (JsonWebKeySet) The public keys of an issuer, in the JSON Web Key Set format of RFC 7517. | |
| condition required | string (TrustRuleCondition) [ 1 .. 4096 ] characters A CEL condition on the claims variable, the content of the token. The rule accepts a token when the condition returns true, for example claims.repository == "acme/billing-agent". |
| agent_name required | string (TrustRuleAgentName) [ 1 .. 4096 ] characters A CEL expression on the claims variable that returns the name of the agent, from 1 to 128 characters, for example claims.repository. |
| environment required | string (Environment) Enum: "production" "test" |
| team | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| owner | string [ 1 .. 256 ] characters The email of the member who answers for the agents of the rule. |
| enabled required | boolean Whether the rule accepts tokens. A disabled rule refuses every exchange, and its agents no longer pass the decision point. |
| agents required | integer <int32> >= 0 The number of agents of the rule. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "issuer": "string",
- "jwks": {
- "keys": [
- {
- "kty": "RSA"
}
]
}, - "condition": "string",
- "agent_name": "string",
- "environment": "production",
- "team": "string",
- "owner": "string",
- "enabled": true,
- "agents": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}An absent field does not change. A field set to null is removed. The environment of a trust rule never changes. Setting enabled to false refuses every exchange of the rule, and the agent tokens of its agents stop working within one second.
| trust_rule_id required | string <uuid> |
| name | string [ 1 .. 128 ] characters |
| issuer | string (TrustRuleIssuer) <= 512 characters ^https://[^\s]+$ The issuer the rule trusts, compared exactly with the iss claim of the token, for example https://token.actions.githubusercontent.com. |
object or null The public keys of the issuer. Null removes them, and the service then reads the keys at the address of the issuer. | |
| condition | string (TrustRuleCondition) [ 1 .. 4096 ] characters A CEL condition on the claims variable, the content of the token. The rule accepts a token when the condition returns true, for example claims.repository == "acme/billing-agent". |
| agent_name | string (TrustRuleAgentName) [ 1 .. 4096 ] characters A CEL expression on the claims variable that returns the name of the agent, from 1 to 128 characters, for example claims.repository. |
| team | string or null <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team of the organization. |
| owner | string or null <email> <= 254 characters The email of a member of the organization, who answers for the agents of the rule. |
| enabled | boolean |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters |
| issuer required | string (TrustRuleIssuer) <= 512 characters ^https://[^\s]+$ The issuer the rule trusts, compared exactly with the iss claim of the token, for example https://token.actions.githubusercontent.com. |
object (JsonWebKeySet) The public keys of an issuer, in the JSON Web Key Set format of RFC 7517. | |
| condition required | string (TrustRuleCondition) [ 1 .. 4096 ] characters A CEL condition on the claims variable, the content of the token. The rule accepts a token when the condition returns true, for example claims.repository == "acme/billing-agent". |
| agent_name required | string (TrustRuleAgentName) [ 1 .. 4096 ] characters A CEL expression on the claims variable that returns the name of the agent, from 1 to 128 characters, for example claims.repository. |
| environment required | string (Environment) Enum: "production" "test" |
| team | string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$ The handle of a team, which never changes, for example customer-support. |
| owner | string [ 1 .. 256 ] characters The email of the member who answers for the agents of the rule. |
| enabled required | boolean Whether the rule accepts tokens. A disabled rule refuses every exchange, and its agents no longer pass the decision point. |
| agents required | integer <int32> >= 0 The number of agents of the rule. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "name": "string",
- "issuer": "string",
- "jwks": {
- "keys": [
- {
- "kty": "RSA"
}
]
}, - "condition": "string",
- "agent_name": "string",
- "team": "string",
- "enabled": true
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "issuer": "string",
- "jwks": {
- "keys": [
- {
- "kty": "RSA"
}
]
}, - "condition": "string",
- "agent_name": "string",
- "environment": "production",
- "team": "string",
- "owner": "string",
- "enabled": true,
- "agents": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}The agents of the rule stay in the registry with their history, without a rule, and their agent tokens stop working within one second. Another rule can adopt them when they hold no active key.
| trust_rule_id required | string <uuid> |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}The exchange of a platform token for an agent token, following OAuth 2.0 Token Exchange, and the sign-in of the Paidwen command on a device, following the OAuth 2.0 Device Authorization Grant. The admin API serves them.
With the token exchange grant, the subject token is a JWT that a platform signed for the agent, such as the projected token of a Kubernetes service account, the OIDC token of a GitHub Actions job or the web identity token of AWS. Its audience is the audience of the organization. The service verifies its signature, its issuer, its audience and its expiry, then tries the enabled trust rules of the organization for its issuer, in the order of their creation. The first rule whose condition accepts the token gives the name of the agent. The service finds the agent of this name, or creates it, and answers with an agent token valid for 15 minutes, which the SDK sends in place of a key. With the device code grant of RFC 8628, the Paidwen command polls every interval seconds with the device code it received. The service answers authorization_pending until a person accepts the code in the dashboard, slow_down to a poll that comes too early, access_denied when the person refuses, and expired_token after 15 minutes. Once the code is accepted, the first poll receives the key of the agent of the person, once, and the service keeps no copy of it. Errors follow RFC 6749.
| grant_type required | string Value: "urn:ietf:params:oauth:grant-type:token-exchange" |
| subject_token required | string The token the platform signed for the agent, with the audience of the organization. |
| subject_token_type required | string Enum: "urn:ietf:params:oauth:token-type:jwt" "urn:ietf:params:oauth:token-type:id_token" |
| requested_token_type | string Value: "urn:ietf:params:oauth:token-type:access_token" |
| audience | string When present, https://api.paidwen.com. |
| resource | string When present, https://api.paidwen.com. |
| Cache-Control | string Always no-store. |
| access_token required | string The agent token, a JWT that follows RFC 9068. The SDK sends it in place of the key of the agent. |
| issued_token_type required | string Value: "urn:ietf:params:oauth:token-type:access_token" |
| token_type required | string Value: "Bearer" |
| expires_in required | integer <int32> The seconds before the agent token expires. |
{- "access_token": "string",
- "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
- "token_type": "Bearer",
- "expires_in": 0
}The sign-ins of the Paidwen command on a device, which a person accepts in the dashboard. The admin API serves them.
The dashboard reads it when the person enters or opens a user code. A person who enters more than 20 unknown codes in an hour receives 429 until the hour ends, as RFC 8628 asks against guessing.
| user_code required | string [ 8 .. 9 ] characters The user code the Paidwen command shows, with or without its hyphen, in any case. |
| user_code required | string^[BCDFGHJKLMNPQRSTVWXZ]{4}-[BCDFGHJKLMNPQRSTV... |
| status required | string (DeviceAuthorizationStatus) Enum: "pending" "approved" "issued" "denied" "expired" pending waits for the person. approved holds the key until the command polls. issued means the command received the key. denied means the person refused. expired means nobody answered within 15 minutes. |
| expires_at required | string <date-time> |
| agent_id | string <uuid> The agent whose key the command receives, once the sign-in is accepted. |
| agent_name | string The name of this agent, the email of the person. |
{- "user_code": "string",
- "status": "pending",
- "expires_at": "2019-08-24T14:15:22Z",
- "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
- "agent_name": "string"
}Accepting gives the command the key of the agent of the signed-in person in the organization of the call. The agent is named by the email of the person, who owns it, in production. The service creates it when it does not exist, then creates a key for it, kept sealed until the command polls once. An agent of this name that another person owns, that a trust rule created, or that already has two active keys answers 409. A refused sign-in answers access_denied to the command. A code already answered or expired answers 409. The role member is required.
| user_code required | string [ 8 .. 9 ] characters The user code the Paidwen command shows, with or without its hyphen, in any case. |
| answer required | string Enum: "approve" "deny" |
| user_code required | string^[BCDFGHJKLMNPQRSTVWXZ]{4}-[BCDFGHJKLMNPQRSTV... |
| status required | string (DeviceAuthorizationStatus) Enum: "pending" "approved" "issued" "denied" "expired" pending waits for the person. approved holds the key until the command polls. issued means the command received the key. denied means the person refused. expired means nobody answered within 15 minutes. |
| expires_at required | string <date-time> |
| agent_id | string <uuid> The agent whose key the command receives, once the sign-in is accepted. |
| agent_name | string The name of this agent, the email of the person. |
{- "answer": "approve"
}{- "user_code": "string",
- "status": "pending",
- "expires_at": "2019-08-24T14:15:22Z",
- "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
- "agent_name": "string"
}| agent_id required | string <uuid> |
required | Array of objects (PermissionEntry) <= 100 items What the agent may do. |
required | Array of objects (PermissionEntry) <= 100 items What the agent may not do. A deny entry always wins over an allow entry. |
{- "allow": [
- {
- "tool": "string",
- "server": "string"
}
], - "deny": [
- {
- "tool": "string",
- "server": "string"
}
]
}As soon as one entry targets the agent, the agent is closed: an action passes only when an allow entry matches it and no deny entry matches it. Two empty lists remove every permission and open the agent again.
| agent_id required | string <uuid> |
required | Array of objects (PermissionEntry) <= 100 items What the agent may do. |
required | Array of objects (PermissionEntry) <= 100 items What the agent may not do. A deny entry always wins over an allow entry. |
required | Array of objects (PermissionEntry) <= 100 items What the agent may do. |
required | Array of objects (PermissionEntry) <= 100 items What the agent may not do. A deny entry always wins over an allow entry. |
{- "allow": [
- {
- "tool": "string",
- "server": "string"
}
], - "deny": [
- {
- "tool": "string",
- "server": "string"
}
]
}{- "allow": [
- {
- "tool": "string",
- "server": "string"
}
], - "deny": [
- {
- "tool": "string",
- "server": "string"
}
]
}| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (Rule) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "condition": "string",
- "verdict": "allow",
- "mode": "active",
- "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
- "source_text": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}The condition must compile and return a boolean, or the rule is refused.
| name | string [ 1 .. 256 ] characters |
| condition required | string [ 1 .. 4096 ] characters |
| verdict required | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" The answer to the agent. From the least to the most strict: allow, require_approval, escalate, block, quarantine. |
| mode required | string (RuleMode) Enum: "active" "observe" An active rule applies its verdict. A rule in observation only reports the verdict it would have given. |
| approval_group_id | string <uuid> |
| source_text | string [ 1 .. 1000 ] characters The sentence the rule was written from, kept for the audit. |
| Location | string The address of the rule. |
| id required | string <uuid> |
| name | string [ 1 .. 256 ] characters |
| condition required | string [ 1 .. 4096 ] characters A CEL expression that returns a boolean. It reads six variables: agent, tool, params, cost, now and firewall. |
| verdict required | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" The answer to the agent. From the least to the most strict: allow, require_approval, escalate, block, quarantine. |
| mode required | string (RuleMode) Enum: "active" "observe" An active rule applies its verdict. A rule in observation only reports the verdict it would have given. |
| approval_group_id | string <uuid> The approval group that answers this rule. Only a rule whose verdict waits for a human answer names a group. Without it, the default group of the verdict answers. |
| source_text | string [ 1 .. 1000 ] characters The sentence the rule was written from. A change of the condition, the verdict or the group without a new sentence removes it. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "name": "string",
- "condition": "string",
- "verdict": "allow",
- "mode": "active",
- "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
- "source_text": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "condition": "string",
- "verdict": "allow",
- "mode": "active",
- "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
- "source_text": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}A model translates the sentence into an exact rule, permissions or budget. Paidwen checks the draft, reads it back from the exact result, replays it on the decisions of the last 30 days and lists its warnings. A rule written in CEL goes through the same check, without the model. Nothing changes until the draft is sent to the route that creates it. The model writes the draft and never decides an action.
| text | string [ 1 .. 1000 ] characters The sentence, in any language. |
| agent_id | string <uuid> The agent the sentence is about, when the sentence comes from the page of an agent. A sentence that names another agent keeps it. |
object (DraftRule) A rule written in CEL. Paidwen reads it back and replays it on the decisions of the last 30 days, without the model, and without counting it in the drafts of the day. |
| kind required | string (DraftKind) Enum: "rule" "permissions" "budget" |
| text required | string |
object (RuleCreate) | |
| agent_id | string <uuid> The agent of the permissions or of the budget. |
object (AgentPermissions) | |
object (AgentPermissions) | |
object (Budget) The limits of the agent per calendar day and per calendar month, in UTC. At a limit, the agent receives block until the next window. | |
| reading required | string The draft read back from the exact rule, permissions or budget, by fixed code and never by the model. Values sit between backticks. |
| complete required | boolean False when a part of the condition has no sentence and stays in CEL. |
required | object (DraftPreview) |
required | Array of objects (DraftWarning) |
{- "text": "string",
- "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
- "rule": {
- "condition": "string",
- "verdict": "allow",
- "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235"
}
}{- "kind": "rule",
- "text": "string",
- "rule": {
- "name": "string",
- "condition": "string",
- "verdict": "allow",
- "mode": "active",
- "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
- "source_text": "string"
}, - "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
- "permissions": {
- "allow": [
- {
- "tool": "string",
- "server": "string"
}
], - "deny": [
- {
- "tool": "string",
- "server": "string"
}
]
}, - "current_permissions": {
- "allow": [
- {
- "tool": "string",
- "server": "string"
}
], - "deny": [
- {
- "tool": "string",
- "server": "string"
}
]
}, - "budget": {
- "daily_usd": 1,
- "monthly_usd": 1
}, - "reading": "string",
- "complete": true,
- "preview": {
- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z",
- "scanned": 0,
- "matched": 0,
- "failed": 0,
- "truncated": true,
- "agents": [
- {
- "agent_id": "string",
- "name": "string",
- "matched": 0
}
], - "tools": [
- {
- "name": "string",
- "matched": 0
}
], - "examples": [
- {
- "action_id": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "agent_id": "string",
- "agent_name": "string",
- "tool_name": "string",
- "verdict": "allow"
}
], - "days": [
- {
- "day": "2019-08-24",
- "spent_usd": 0.1
}
]
}, - "warnings": [
- {
- "code": "broad",
- "text": "string"
}
]
}| rule_id required | string <uuid> |
| id required | string <uuid> |
| name | string [ 1 .. 256 ] characters |
| condition required | string [ 1 .. 4096 ] characters A CEL expression that returns a boolean. It reads six variables: agent, tool, params, cost, now and firewall. |
| verdict required | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" The answer to the agent. From the least to the most strict: allow, require_approval, escalate, block, quarantine. |
| mode required | string (RuleMode) Enum: "active" "observe" An active rule applies its verdict. A rule in observation only reports the verdict it would have given. |
| approval_group_id | string <uuid> The approval group that answers this rule. Only a rule whose verdict waits for a human answer names a group. Without it, the default group of the verdict answers. |
| source_text | string [ 1 .. 1000 ] characters The sentence the rule was written from. A change of the condition, the verdict or the group without a new sentence removes it. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "condition": "string",
- "verdict": "allow",
- "mode": "active",
- "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
- "source_text": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Setting mode to observe or active switches the rule, in both directions.
| rule_id required | string <uuid> |
| name | string or null [ 1 .. 256 ] characters |
| condition | string [ 1 .. 4096 ] characters |
| verdict | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" The answer to the agent. From the least to the most strict: allow, require_approval, escalate, block, quarantine. |
| mode | string (RuleMode) Enum: "active" "observe" An active rule applies its verdict. A rule in observation only reports the verdict it would have given. |
| approval_group_id | string or null <uuid> |
| source_text | string or null [ 1 .. 1000 ] characters |
| id required | string <uuid> |
| name | string [ 1 .. 256 ] characters |
| condition required | string [ 1 .. 4096 ] characters A CEL expression that returns a boolean. It reads six variables: agent, tool, params, cost, now and firewall. |
| verdict required | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" The answer to the agent. From the least to the most strict: allow, require_approval, escalate, block, quarantine. |
| mode required | string (RuleMode) Enum: "active" "observe" An active rule applies its verdict. A rule in observation only reports the verdict it would have given. |
| approval_group_id | string <uuid> The approval group that answers this rule. Only a rule whose verdict waits for a human answer names a group. Without it, the default group of the verdict answers. |
| source_text | string [ 1 .. 1000 ] characters The sentence the rule was written from. A change of the condition, the verdict or the group without a new sentence removes it. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "name": "string",
- "condition": "string",
- "verdict": "allow",
- "mode": "active",
- "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
- "source_text": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "condition": "string",
- "verdict": "allow",
- "mode": "active",
- "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
- "source_text": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Who approves what, on which channel, and what happens without an answer. The admin API serves them.
| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (ApprovalGroup) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "slack_channel": "string",
- "teams_webhook_host": "string",
- "expires_in": 60,
- "on_expiry": "deny",
- "default_for": [
- "require_approval"
], - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}Naming a verdict in default_for makes the group the default group of that verdict, in place of the group that held it before.
| name required | string [ 1 .. 128 ] characters |
| members required | Array of strings <email> [ 1 .. 100 ] items unique [ items <email > <= 254 characters ] |
| slack_channel | string^[CG][A-Z0-9]{2,31}$ |
| teams_webhook_url | string <password> (TeamsWebhookURL) <= 2048 characters ^https?://\S+$ The address of the webhook that a Teams workflow gives, such as the template Send webhook alerts to a channel. Its host ends with .environment.api.powerplatform.com. The service seals it and shows only its host afterwards. |
| expires_in | integer <int32> [ 60 .. 86400 ] Without it, the group takes the approval_expires_in of the organization. |
| on_expiry | string Enum: "deny" "allow" Without it, the group takes the approval_on_expiry of the organization. |
| default_for | Array of strings (WaitingVerdict) <= 2 items unique Items Enum: "require_approval" "escalate" |
| Location | string The address of the approval group. |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters |
| members required | Array of strings <email> [ 1 .. 100 ] items unique [ items <email > <= 254 characters ] The email addresses of the people who approve. Each receives the request by email, and may answer in Slack. |
| slack_channel | string^[CG][A-Z0-9]{2,31}$ The Slack channel that receives the request, in the workspace connected to the organization. |
| teams_webhook_host | string The host of the Microsoft Teams webhook that receives the request. The service keeps the address sealed and never shows it again. |
| expires_in required | integer <int32> (ExpiresIn) [ 60 .. 86400 ] Seconds before a wait expires without an answer. |
| on_expiry required | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| default_for required | Array of strings (WaitingVerdict) <= 2 items unique Items Enum: "require_approval" "escalate" The verdicts this group answers when a rule names no group. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "name": "string",
- "slack_channel": "string",
- "teams_webhook_url": "pa$$word",
- "expires_in": 60,
- "on_expiry": "deny",
- "default_for": [
- "require_approval"
]
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "slack_channel": "string",
- "teams_webhook_host": "string",
- "expires_in": 60,
- "on_expiry": "deny",
- "default_for": [
- "require_approval"
], - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| group_id required | string <uuid> |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters |
| members required | Array of strings <email> [ 1 .. 100 ] items unique [ items <email > <= 254 characters ] The email addresses of the people who approve. Each receives the request by email, and may answer in Slack. |
| slack_channel | string^[CG][A-Z0-9]{2,31}$ The Slack channel that receives the request, in the workspace connected to the organization. |
| teams_webhook_host | string The host of the Microsoft Teams webhook that receives the request. The service keeps the address sealed and never shows it again. |
| expires_in required | integer <int32> (ExpiresIn) [ 60 .. 86400 ] Seconds before a wait expires without an answer. |
| on_expiry required | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| default_for required | Array of strings (WaitingVerdict) <= 2 items unique Items Enum: "require_approval" "escalate" The verdicts this group answers when a rule names no group. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "slack_channel": "string",
- "teams_webhook_host": "string",
- "expires_in": 60,
- "on_expiry": "deny",
- "default_for": [
- "require_approval"
], - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| group_id required | string <uuid> |
| name | string [ 1 .. 128 ] characters |
| members | Array of strings <email> [ 1 .. 100 ] items unique [ items <email > <= 254 characters ] |
| slack_channel | string or null^[CG][A-Z0-9]{2,31}$ |
| teams_webhook_url | string or null <password> <= 2048 characters ^https?://\S+$ The address of the webhook that a Teams workflow gives. Null removes it. |
| expires_in | integer <int32> (ExpiresIn) [ 60 .. 86400 ] Seconds before a wait expires without an answer. |
| on_expiry | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| default_for | Array of strings (WaitingVerdict) <= 2 items unique Items Enum: "require_approval" "escalate" |
| id required | string <uuid> |
| name required | string [ 1 .. 128 ] characters |
| members required | Array of strings <email> [ 1 .. 100 ] items unique [ items <email > <= 254 characters ] The email addresses of the people who approve. Each receives the request by email, and may answer in Slack. |
| slack_channel | string^[CG][A-Z0-9]{2,31}$ The Slack channel that receives the request, in the workspace connected to the organization. |
| teams_webhook_host | string The host of the Microsoft Teams webhook that receives the request. The service keeps the address sealed and never shows it again. |
| expires_in required | integer <int32> (ExpiresIn) [ 60 .. 86400 ] Seconds before a wait expires without an answer. |
| on_expiry required | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| default_for required | Array of strings (WaitingVerdict) <= 2 items unique Items Enum: "require_approval" "escalate" The verdicts this group answers when a rule names no group. |
| created_at required | string <date-time> |
| updated_at required | string <date-time> |
{- "name": "string",
- "slack_channel": "string",
- "teams_webhook_url": "pa$$word",
- "expires_in": 60,
- "on_expiry": "deny",
- "default_for": [
- "require_approval"
]
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "slack_channel": "string",
- "teams_webhook_host": "string",
- "expires_in": 60,
- "on_expiry": "deny",
- "default_for": [
- "require_approval"
], - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| group_id required | string <uuid> |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}| status | string (ApprovalState) Enum: "pending" "approved" "denied" "expired" Only the approvals in this state. |
| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (ApprovalRequest) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "agent": {
- "id": "string",
- "name": "string"
}, - "tool": {
- "name": "string",
- "kind": "function",
- "server": "string"
}, - "params": { },
- "cost": {
- "estimated_usd": 0
}, - "verdict": "require_approval",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}, - "group_id": "306db4e0-7449-4501-b76f-075576fe2d8f",
- "status": "pending",
- "expires_at": "2019-08-24T14:15:22Z",
- "on_expiry": "deny",
- "channel": "slack",
- "answered_by": "string",
- "answered_at": "2019-08-24T14:15:22Z",
- "comment": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}The dashboard opens an approval by its identifier, for example from the buttons of the card that Microsoft Teams shows.
| approval_id required | string <uuid> |
| id required | string <uuid> |
| action_id required | string <uuid> |
required | object (AgentReference) |
required | object (Tool) |
object The parameters of the action. They are absent when the agent does not keep its content. | |
object (Cost) | |
| verdict required | string (WaitingVerdict) Enum: "require_approval" "escalate" A verdict that waits for a human answer. |
object (RuleReference) | |
| group_id | string <uuid> |
| status required | string (ApprovalState) Enum: "pending" "approved" "denied" "expired" The state of an approval. pending waits for a human answer, approved and denied carry the answer, expired means no answer came before the deadline. They follow authorization_pending, the issued token, access_denied and expired_token of OpenID CIBA. |
| expires_at required | string <date-time> |
| on_expiry required | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| channel | string (ApprovalChannel) Enum: "slack" "email" "api" "dashboard" "expiry" Where the answer came from. expiry means that no one answered before the deadline. |
| answered_by | string The email of the approver, or the redacted admin key that answered through the API. |
| answered_at | string <date-time> |
| comment | string <= 1000 characters |
| created_at required | string <date-time> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "agent": {
- "id": "string",
- "name": "string"
}, - "tool": {
- "name": "string",
- "kind": "function",
- "server": "string"
}, - "params": { },
- "cost": {
- "estimated_usd": 0
}, - "verdict": "require_approval",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}, - "group_id": "306db4e0-7449-4501-b76f-075576fe2d8f",
- "status": "pending",
- "expires_at": "2019-08-24T14:15:22Z",
- "on_expiry": "deny",
- "channel": "slack",
- "answered_by": "string",
- "answered_at": "2019-08-24T14:15:22Z",
- "comment": "string",
- "created_at": "2019-08-24T14:15:22Z"
}The first answer wins. An approval that is already answered or expired answers 409. Before the human accounts, the answer is attributed to the admin key that sends it.
| approval_id required | string <uuid> |
| answer required | string (ApprovalAnswerValue) Enum: "approve" "deny" |
| comment | string [ 1 .. 1000 ] characters |
| id required | string <uuid> |
| action_id required | string <uuid> |
required | object (AgentReference) |
required | object (Tool) |
object The parameters of the action. They are absent when the agent does not keep its content. | |
object (Cost) | |
| verdict required | string (WaitingVerdict) Enum: "require_approval" "escalate" A verdict that waits for a human answer. |
object (RuleReference) | |
| group_id | string <uuid> |
| status required | string (ApprovalState) Enum: "pending" "approved" "denied" "expired" The state of an approval. pending waits for a human answer, approved and denied carry the answer, expired means no answer came before the deadline. They follow authorization_pending, the issued token, access_denied and expired_token of OpenID CIBA. |
| expires_at required | string <date-time> |
| on_expiry required | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| channel | string (ApprovalChannel) Enum: "slack" "email" "api" "dashboard" "expiry" Where the answer came from. expiry means that no one answered before the deadline. |
| answered_by | string The email of the approver, or the redacted admin key that answered through the API. |
| answered_at | string <date-time> |
| comment | string <= 1000 characters |
| created_at required | string <date-time> |
{- "answer": "approve",
- "comment": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "agent": {
- "id": "string",
- "name": "string"
}, - "tool": {
- "name": "string",
- "kind": "function",
- "server": "string"
}, - "params": { },
- "cost": {
- "estimated_usd": 0
}, - "verdict": "require_approval",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}, - "group_id": "306db4e0-7449-4501-b76f-075576fe2d8f",
- "status": "pending",
- "expires_at": "2019-08-24T14:15:22Z",
- "on_expiry": "deny",
- "channel": "slack",
- "answered_by": "string",
- "answered_at": "2019-08-24T14:15:22Z",
- "comment": "string",
- "created_at": "2019-08-24T14:15:22Z"
}Mail link scanners open links by themselves, so opening the link never answers. The page shows the action and two buttons, which send the answer by a form.
| token required | string^[A-Za-z0-9_-]{43}$ The secret of the personal link, 32 random bytes in unpadded base64url. |
The link proves the identity of the member it was sent to. It serves once.
| token required | string^[A-Za-z0-9_-]{43}$ The secret of the personal link, 32 random bytes in unpadded base64url. |
| answer required | string (ApprovalAnswerValue) Enum: "approve" "deny" |
Who did what, when, why, with which agent and with which permission, read from the journal. The admin API serves it.
The period runs from from, included, to to, excluded, and lasts at most 366 days. The audit is built from the journal only.
| from required | string <date-time> The start of the period, included. |
| to required | string <date-time> The end of the period, excluded. |
| agent_id | string <uuid> Only the actions of this agent. |
| format | string Default: "json" Enum: "json" "csv" json for a JSON array of records, csv for a CSV file with one line per action. |
| action_id required | string <uuid> |
required | object (AuditAgent) The agent as the decision point knew it when it decided. |
required | object (Tool) |
object | |
object (Cost) | |
| session_id | string |
| decided_at required | string <date-time> |
| verdict required | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" The answer to the agent. From the least to the most strict: allow, require_approval, escalate, block, quarantine. |
object (RuleReference) | |
required | Array of objects (ObservedRule) |
object (PermissionOutcome) How the permissions of the agent answered. When allowed is false, the permissions count as block. The tool and server patterns name the entry that decided; they are absent when no entry lists the tool. | |
object (BudgetOutcome) The budget of the agent refused the action, and counts as block. The spent amount had reached the limit, or the spent amount and the estimated cost would exceed it. | |
object (AuditApproval) | |
object (AuditExecution) The call of the tool by the agent, from its request until its return. | |
object (IncidentReference) | |
Array of objects The journal lines the record comes from, following contracts/journal.schema.json. |
[- {
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "agent": {
- "id": "string",
- "name": "string",
- "environment": "production"
}, - "tool": {
- "name": "string",
- "kind": "function",
- "server": "string"
}, - "params": { },
- "cost": {
- "estimated_usd": 0
}, - "session_id": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "verdict": "allow",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}, - "observed": [
- {
- "rule_id": "string",
- "verdict": "allow"
}
], - "permission": {
- "allowed": true,
- "tool": "string",
- "server": "string"
}, - "budget": {
- "exceeded": "daily",
- "spent_usd": 0,
- "limit_usd": 0
}, - "approval": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "status": "pending",
- "channel": "slack",
- "answered_by": "string",
- "answered_at": "2019-08-24T14:15:22Z",
- "comment": "string"
}, - "execution": {
- "requested_at": "2019-08-24T14:15:22Z",
- "started_at": "2019-08-24T14:15:22Z",
- "ended_at": "2019-08-24T14:15:22Z",
- "status": "ok",
- "error_type": "string"
}, - "incident": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "quarantine"
}, - "lines": [
- { }
]
}
]The pack holds the complete lists that an auditor samples from, in CSV and in JSON Lines, a report that sorts them under the requirements of the framework, a manifest with the SHA-256 digest of every file, and the RSA signature of the manifest. It is not an audit report. HIPAA and the AI Act need the agents in scope. The period lasts at most 366 days.
| framework required | string Enum: "soc2" "iso27001" "hipaa" "ai-act" The framework whose requirements sort the lists. |
| from required | string <date-time> The start of the period, included. |
| to required | string <date-time> The end of the period, excluded. |
| agent_id | Array of strings <uuid> <= 100 items [ items <uuid > ] The agents in scope. HIPAA and the AI Act need at least one. |
| Content-Disposition | string The name of the file. |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}The manifest of a pack names its key in key_id. A retired key stays in the list, so that its packs still verify.
required | Array of objects (EvidenceKey) |
{- "data": [
- {
- "key_id": "string",
- "algorithm": "RS256",
- "public_key": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "retires_at": "2019-08-24T14:15:22Z"
}
]
}The record is built from the journal only, with the journal lines it comes from.
| action_id required | string <uuid> |
| action_id required | string <uuid> |
required | object (AuditAgent) The agent as the decision point knew it when it decided. |
required | object (Tool) |
object | |
object (Cost) | |
| session_id | string |
| decided_at required | string <date-time> |
| verdict required | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" The answer to the agent. From the least to the most strict: allow, require_approval, escalate, block, quarantine. |
object (RuleReference) | |
required | Array of objects (ObservedRule) |
object (PermissionOutcome) How the permissions of the agent answered. When allowed is false, the permissions count as block. The tool and server patterns name the entry that decided; they are absent when no entry lists the tool. | |
object (BudgetOutcome) The budget of the agent refused the action, and counts as block. The spent amount had reached the limit, or the spent amount and the estimated cost would exceed it. | |
object (AuditApproval) | |
object (AuditExecution) The call of the tool by the agent, from its request until its return. | |
object (IncidentReference) | |
Array of objects The journal lines the record comes from, following contracts/journal.schema.json. |
{- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "agent": {
- "id": "string",
- "name": "string",
- "environment": "production"
}, - "tool": {
- "name": "string",
- "kind": "function",
- "server": "string"
}, - "params": { },
- "cost": {
- "estimated_usd": 0
}, - "session_id": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "verdict": "allow",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}, - "observed": [
- {
- "rule_id": "string",
- "verdict": "allow"
}
], - "permission": {
- "allowed": true,
- "tool": "string",
- "server": "string"
}, - "budget": {
- "exceeded": "daily",
- "spent_usd": 0,
- "limit_usd": 0
}, - "approval": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "status": "pending",
- "channel": "slack",
- "answered_by": "string",
- "answered_at": "2019-08-24T14:15:22Z",
- "comment": "string"
}, - "execution": {
- "requested_at": "2019-08-24T14:15:22Z",
- "started_at": "2019-08-24T14:15:22Z",
- "ended_at": "2019-08-24T14:15:22Z",
- "status": "ok",
- "error_type": "string"
}, - "incident": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "quarantine"
}, - "lines": [
- { }
]
}The gestures that cut an agent, quarantine it, revoke its keys or change its key, and the incidents they open. The admin API serves them.
Every decision of the agent answers quarantine until someone releases it. The agent still signs in, and its requests still reach the journal. An agent already in quarantine answers its open incident. A disabled agent answers 409. The contacts of the organization receive the incident.
| agent_id required | string <uuid> |
| reason | string [ 1 .. 1000 ] characters Why the gesture is made, kept in the incident and the journal. |
| id required | string <uuid> |
required | object (AgentReference) |
| kind required | string (IncidentKind) Enum: "quarantine" "disable" "revoke_keys" "rotate_key" The gesture that opened the incident. |
| state required | string (IncidentState) Enum: "open" "lifted" "done" open while the quarantine or the disabling holds, lifted once someone ends it, done for a revocation or a key change, which stays. |
| reason | string <= 1000 characters |
| action_id | string <uuid> The action that made a rule quarantine the agent. |
| keys_revoked | integer <int32> >= 0 The active keys a revocation or a key change revoked. |
required | object (IncidentActor) Who made a gesture, a person, an admin key or a rule. |
| opened_at required | string <date-time> |
object (IncidentActor) Who made a gesture, a person, an admin key or a rule. | |
| lifted_at | string <date-time> |
| lift_reason | string <= 1000 characters |
{- "reason": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent": {
- "id": "string",
- "name": "string"
}, - "kind": "quarantine",
- "state": "open",
- "reason": "string",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "keys_revoked": 0,
- "opened_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "opened_at": "2019-08-24T14:15:22Z",
- "lifted_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "lifted_at": "2019-08-24T14:15:22Z",
- "lift_reason": "string"
}An agent that is not in quarantine answers 409.
| agent_id required | string <uuid> |
| reason | string [ 1 .. 1000 ] characters Why the gesture is made, kept in the incident and the journal. |
| id required | string <uuid> |
required | object (AgentReference) |
| kind required | string (IncidentKind) Enum: "quarantine" "disable" "revoke_keys" "rotate_key" The gesture that opened the incident. |
| state required | string (IncidentState) Enum: "open" "lifted" "done" open while the quarantine or the disabling holds, lifted once someone ends it, done for a revocation or a key change, which stays. |
| reason | string <= 1000 characters |
| action_id | string <uuid> The action that made a rule quarantine the agent. |
| keys_revoked | integer <int32> >= 0 The active keys a revocation or a key change revoked. |
required | object (IncidentActor) Who made a gesture, a person, an admin key or a rule. |
| opened_at required | string <date-time> |
object (IncidentActor) Who made a gesture, a person, an admin key or a rule. | |
| lifted_at | string <date-time> |
| lift_reason | string <= 1000 characters |
{- "reason": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent": {
- "id": "string",
- "name": "string"
}, - "kind": "quarantine",
- "state": "open",
- "reason": "string",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "keys_revoked": 0,
- "opened_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "opened_at": "2019-08-24T14:15:22Z",
- "lifted_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "lifted_at": "2019-08-24T14:15:22Z",
- "lift_reason": "string"
}The decision point refuses every request of the agent with 403 until someone enables it. A quarantine in progress ends, replaced by the disabling. An agent already disabled answers its open incident.
| agent_id required | string <uuid> |
| reason | string [ 1 .. 1000 ] characters Why the gesture is made, kept in the incident and the journal. |
| id required | string <uuid> |
required | object (AgentReference) |
| kind required | string (IncidentKind) Enum: "quarantine" "disable" "revoke_keys" "rotate_key" The gesture that opened the incident. |
| state required | string (IncidentState) Enum: "open" "lifted" "done" open while the quarantine or the disabling holds, lifted once someone ends it, done for a revocation or a key change, which stays. |
| reason | string <= 1000 characters |
| action_id | string <uuid> The action that made a rule quarantine the agent. |
| keys_revoked | integer <int32> >= 0 The active keys a revocation or a key change revoked. |
required | object (IncidentActor) Who made a gesture, a person, an admin key or a rule. |
| opened_at required | string <date-time> |
object (IncidentActor) Who made a gesture, a person, an admin key or a rule. | |
| lifted_at | string <date-time> |
| lift_reason | string <= 1000 characters |
{- "reason": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent": {
- "id": "string",
- "name": "string"
}, - "kind": "quarantine",
- "state": "open",
- "reason": "string",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "keys_revoked": 0,
- "opened_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "opened_at": "2019-08-24T14:15:22Z",
- "lifted_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "lifted_at": "2019-08-24T14:15:22Z",
- "lift_reason": "string"
}An agent that is not disabled answers 409.
| agent_id required | string <uuid> |
| reason | string [ 1 .. 1000 ] characters Why the gesture is made, kept in the incident and the journal. |
| id required | string <uuid> |
required | object (AgentReference) |
| kind required | string (IncidentKind) Enum: "quarantine" "disable" "revoke_keys" "rotate_key" The gesture that opened the incident. |
| state required | string (IncidentState) Enum: "open" "lifted" "done" open while the quarantine or the disabling holds, lifted once someone ends it, done for a revocation or a key change, which stays. |
| reason | string <= 1000 characters |
| action_id | string <uuid> The action that made a rule quarantine the agent. |
| keys_revoked | integer <int32> >= 0 The active keys a revocation or a key change revoked. |
required | object (IncidentActor) Who made a gesture, a person, an admin key or a rule. |
| opened_at required | string <date-time> |
object (IncidentActor) Who made a gesture, a person, an admin key or a rule. | |
| lifted_at | string <date-time> |
| lift_reason | string <= 1000 characters |
{- "reason": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent": {
- "id": "string",
- "name": "string"
}, - "kind": "quarantine",
- "state": "open",
- "reason": "string",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "keys_revoked": 0,
- "opened_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "opened_at": "2019-08-24T14:15:22Z",
- "lifted_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "lifted_at": "2019-08-24T14:15:22Z",
- "lift_reason": "string"
}The agent signs in no more until it receives a new key.
| agent_id required | string <uuid> |
| reason | string [ 1 .. 1000 ] characters Why the gesture is made, kept in the incident and the journal. |
| id required | string <uuid> |
required | object (AgentReference) |
| kind required | string (IncidentKind) Enum: "quarantine" "disable" "revoke_keys" "rotate_key" The gesture that opened the incident. |
| state required | string (IncidentState) Enum: "open" "lifted" "done" open while the quarantine or the disabling holds, lifted once someone ends it, done for a revocation or a key change, which stays. |
| reason | string <= 1000 characters |
| action_id | string <uuid> The action that made a rule quarantine the agent. |
| keys_revoked | integer <int32> >= 0 The active keys a revocation or a key change revoked. |
required | object (IncidentActor) Who made a gesture, a person, an admin key or a rule. |
| opened_at required | string <date-time> |
object (IncidentActor) Who made a gesture, a person, an admin key or a rule. | |
| lifted_at | string <date-time> |
| lift_reason | string <= 1000 characters |
{- "reason": "string"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent": {
- "id": "string",
- "name": "string"
}, - "kind": "quarantine",
- "state": "open",
- "reason": "string",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "keys_revoked": 0,
- "opened_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "opened_at": "2019-08-24T14:15:22Z",
- "lifted_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "lifted_at": "2019-08-24T14:15:22Z",
- "lift_reason": "string"
}The response carries the new key once, in secret.
| agent_id required | string <uuid> |
| reason | string [ 1 .. 1000 ] characters Why the gesture is made, kept in the incident and the journal. |
required | object (Incident) |
required | object (CreatedAgentKey) |
{- "reason": "string"
}{- "incident": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent": {
- "id": "string",
- "name": "string"
}, - "kind": "quarantine",
- "state": "open",
- "reason": "string",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "keys_revoked": 0,
- "opened_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "opened_at": "2019-08-24T14:15:22Z",
- "lifted_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "lifted_at": "2019-08-24T14:15:22Z",
- "lift_reason": "string"
}, - "key": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
- "redacted": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z",
- "secret": "pa$$word"
}
}| state | string (IncidentState) Enum: "open" "lifted" "done" Only the incidents in this state. |
| agent_id | string <uuid> Only the actions of this agent. |
| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (Incident) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent": {
- "id": "string",
- "name": "string"
}, - "kind": "quarantine",
- "state": "open",
- "reason": "string",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "keys_revoked": 0,
- "opened_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "opened_at": "2019-08-24T14:15:22Z",
- "lifted_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "lifted_at": "2019-08-24T14:15:22Z",
- "lift_reason": "string"
}
], - "has_more": true
}| incident_id required | string <uuid> |
| id required | string <uuid> |
required | object (AgentReference) |
| kind required | string (IncidentKind) Enum: "quarantine" "disable" "revoke_keys" "rotate_key" The gesture that opened the incident. |
| state required | string (IncidentState) Enum: "open" "lifted" "done" open while the quarantine or the disabling holds, lifted once someone ends it, done for a revocation or a key change, which stays. |
| reason | string <= 1000 characters |
| action_id | string <uuid> The action that made a rule quarantine the agent. |
| keys_revoked | integer <int32> >= 0 The active keys a revocation or a key change revoked. |
required | object (IncidentActor) Who made a gesture, a person, an admin key or a rule. |
| opened_at required | string <date-time> |
object (IncidentActor) Who made a gesture, a person, an admin key or a rule. | |
| lifted_at | string <date-time> |
| lift_reason | string <= 1000 characters |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "agent": {
- "id": "string",
- "name": "string"
}, - "kind": "quarantine",
- "state": "open",
- "reason": "string",
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "keys_revoked": 0,
- "opened_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "opened_at": "2019-08-24T14:15:22Z",
- "lifted_by": {
- "kind": "person",
- "email": "string",
- "redacted": "string",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}
}, - "lifted_at": "2019-08-24T14:15:22Z",
- "lift_reason": "string"
}The live feed of the actions, the costs per agent and per day, and the activity of an agent, read from the journal. The admin API serves them.
Each action carries an opaque cursor. before reads the actions older than a cursor, and after reads the actions more recent than a cursor, at most 15 minutes back, which feeds the live view.
| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| before | string^[A-Za-z0-9_-]{1,64}$ The cursor of an action. The page holds the actions older than it. |
| after | string^[A-Za-z0-9_-]{1,64}$ The cursor of an action. The page holds the actions more recent than it, at most 15 minutes back. |
| agent_id | string <uuid> Only the actions of this agent. |
| verdict | string (Verdict) Enum: "allow" "require_approval" "escalate" "block" "quarantine" Only the actions that received this verdict. |
| tool | string [ 1 .. 256 ] characters Only the actions whose tool name starts with this text. |
| from | string <date-time> The start of the period, included. |
| to | string <date-time> The end of the period, excluded. |
required | Array of objects (Action) |
| has_more required | boolean |
{- "data": [
- {
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "cursor": "string",
- "agent": {
- "id": "string",
- "name": "string",
- "environment": "production"
}, - "tool": {
- "name": "string",
- "kind": "function",
- "server": "string"
}, - "verdict": "allow",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}, - "observed": [
- {
- "rule_id": "string",
- "verdict": "allow"
}
], - "permission": {
- "allowed": true,
- "tool": "string",
- "server": "string"
}, - "budget": {
- "exceeded": "daily",
- "spent_usd": 0,
- "limit_usd": 0
}, - "cost": {
- "estimated_usd": 0
}, - "session_id": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "approval": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "status": "pending",
- "channel": "slack",
- "answered_by": "string",
- "answered_at": "2019-08-24T14:15:22Z",
- "comment": "string"
}, - "incident": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "quarantine"
}, - "execution": {
- "requested_at": "2019-08-24T14:15:22Z",
- "started_at": "2019-08-24T14:15:22Z",
- "ended_at": "2019-08-24T14:15:22Z",
- "status": "ok",
- "error_type": "string"
}
}
], - "has_more": true
}A day counts what the budget of each agent counts: the calls to a model, the actions allowed at their decision, and the actions approved, or expired with on_expiry set to allow, at their answer. The period runs from from, included, to to, excluded, and lasts at most 366 days.
| from required | string <date-time> The start of the period, included. |
| to required | string <date-time> The end of the period, excluded. |
| agent_id | string <uuid> Only the actions of this agent. |
| from required | string <date-time> |
| to required | string <date-time> |
required | Array of objects (CostDay) One line per day and per agent that cost something or acted, in UTC. |
{- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z",
- "days": [
- {
- "day": "2019-08-24",
- "agent": {
- "id": "string",
- "name": "string"
}, - "models_usd": 0,
- "tools_usd": 0,
- "decisions": 0,
- "model_calls": 0
}
]
}A session gathers the journal lines that carry the same gen_ai.conversation.id, which the SDK sets from the session_id of its context. Each session carries an opaque cursor, and before reads the sessions that ended earlier.
| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| before | string^[A-Za-z0-9_-]{1,512}$ The cursor of a session. The page holds the sessions that ended before it. |
| agent_id | string <uuid> Only the actions of this agent. |
| from | string <date-time> The start of the period, included. |
| to | string <date-time> The end of the period, excluded. |
required | Array of objects (AgentSession) |
| has_more required | boolean |
{- "data": [
- {
- "id": "string",
- "cursor": "string",
- "agents": [
- {
- "id": "string",
- "name": "string",
- "environment": "production"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "ended_at": "2019-08-24T14:15:22Z",
- "steps": 0,
- "decisions": 0,
- "blocked": 0,
- "waited": 0,
- "errors": 0,
- "cost_usd": 0.1
}
], - "has_more": true
}A step is a call to the model or an action. A call to the model shows only the input messages that the previous call of the same agent did not already show. An action holds its decision, its human answer and its execution. after reads the steps that follow a cursor.
| session_id required | string [ 1 .. 256 ] characters |
| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| after | string^[A-Za-z0-9_-]{1,64}$ The cursor of a step. The page holds the steps that follow it. |
| session_id required | string |
required | Array of objects (SessionStep) |
| has_more required | boolean |
{- "session_id": "string",
- "data": [
- {
- "kind": "model_call",
- "at": "2019-08-24T14:15:22Z",
- "cursor": "string",
- "model_call": {
- "span_id": "string",
- "agent": {
- "id": "string",
- "name": "string",
- "environment": "production"
}, - "provider": "string",
- "model": "string",
- "operation": "string",
- "started_at": "2019-08-24T14:15:22Z",
- "ended_at": "2019-08-24T14:15:22Z",
- "status": "ok",
- "error_type": "string",
- "input_tokens": 0,
- "output_tokens": 0,
- "cost_usd": 0.1,
- "history": 0,
- "system_instructions": [
- { }
], - "input": [
- {
- "role": "string",
- "parts": [
- {
- "type": "string"
}
], - "finish_reason": "string"
}
], - "output": [
- {
- "role": "string",
- "parts": [
- {
- "type": "string"
}
], - "finish_reason": "string"
}
]
}, - "action": {
- "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
- "agent": {
- "id": "string",
- "name": "string",
- "environment": "production"
}, - "tool": {
- "name": "string",
- "kind": "function",
- "server": "string"
}, - "params": { },
- "cost": {
- "estimated_usd": 0
}, - "session_id": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "verdict": "allow",
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}, - "observed": [
- {
- "rule_id": "string",
- "verdict": "allow"
}
], - "permission": {
- "allowed": true,
- "tool": "string",
- "server": "string"
}, - "budget": {
- "exceeded": "daily",
- "spent_usd": 0,
- "limit_usd": 0
}, - "approval": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "status": "pending",
- "channel": "slack",
- "answered_by": "string",
- "answered_at": "2019-08-24T14:15:22Z",
- "comment": "string"
}, - "execution": {
- "requested_at": "2019-08-24T14:15:22Z",
- "started_at": "2019-08-24T14:15:22Z",
- "ended_at": "2019-08-24T14:15:22Z",
- "status": "ok",
- "error_type": "string"
}, - "incident": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "kind": "quarantine"
}, - "lines": [
- { }
]
}
}
], - "has_more": true
}The map gathers the decisions of the period. An edge goes from the caller of an action to its agent, and from the agent to the server or the function of its tool. Without agent_id, the map keeps the 200 most active agents and counts the others in hidden_agents. With agent_id, it keeps the agent, its 50 most active callers and its 50 most active targets.
| period | string (MapPeriod) Enum: "24h" "7d" "30d" The period of the map, ending now. 30d by default. |
| environment | string (Environment) Enum: "production" "test" The environment of the agents on the map. production by default. |
| agent_id | string <uuid> Only the actions of this agent. |
| period_start required | string <date-time> |
| period_end required | string <date-time> |
| environment required | string (Environment) Enum: "production" "test" |
required | Array of objects (MapNode) |
required | Array of objects (MapEdge) |
| hidden_agents required | integer <int64> The active agents that the map leaves out. |
{- "period_start": "2019-08-24T14:15:22Z",
- "period_end": "2019-08-24T14:15:22Z",
- "environment": "production",
- "nodes": [
- {
- "id": "string",
- "kind": "agent",
- "name": "string",
- "agent_id": "string",
- "actions": 0
}
], - "edges": [
- {
- "source": "string",
- "target": "string",
- "tools": [
- "string"
], - "actions": 0,
- "allowed": 0,
- "waited": 0,
- "blocked": 0,
- "errors": 0,
- "cost_usd": 0.1,
- "last_at": "2019-08-24T14:15:22Z"
}
], - "hidden_agents": 0
}| agent_id required | string <uuid> |
| from required | string <date-time> The start of the period, included. |
| to required | string <date-time> The end of the period, excluded. |
| from required | string <date-time> |
| to required | string <date-time> |
required | object (VerdictCounts) |
required | Array of objects (RuleActivity) |
| models_usd required | number <double> |
| tools_usd required | number <double> |
{- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z",
- "verdicts": {
- "allow": 0,
- "require_approval": 0,
- "escalate": 0,
- "block": 0,
- "quarantine": 0
}, - "rules": [
- {
- "rule": {
- "id": "string",
- "name": "string",
- "condition": "string"
}, - "decided": 0,
- "observed": 0
}
], - "models_usd": 0.1,
- "tools_usd": 0.1
}The three ways a person signs in to the dashboard, with Google, with GitHub or with a link sent by email. The admin API serves them.
Keeps the PKCE verifier, the state and the nonce in a cookie for 10 minutes, then sends the browser to Google.
| return_to | string <= 512 characters ^/([A-Za-z0-9_.~-][A-Za-z0-9/_.~?=&%-]*)?$ The page of the dashboard the browser opens after signing in, a path that starts with a single slash. |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}Checks the state against the cookie, exchanges the code, checks the identity token, opens a session, then sends the browser back to the dashboard. A failed sign-in sends the browser to the sign-in page with its reason.
| code | string <= 2048 characters The authorization code the provider gives back. |
| state | string <= 256 characters The state the service gave to the provider, compared with its cookie. |
| error | string <= 256 characters The error the provider gives back when the person refused or the sign-in failed. |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}Keeps the PKCE verifier and the state in a cookie for 10 minutes, then sends the browser to GitHub.
| return_to | string <= 512 characters ^/([A-Za-z0-9_.~-][A-Za-z0-9/_.~?=&%-]*)?$ The page of the dashboard the browser opens after signing in, a path that starts with a single slash. |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}Checks the state against the cookie, exchanges the code, reads the GitHub identifier and the verified primary email of the person, opens a session, then sends the browser back to the dashboard.
| code | string <= 2048 characters The authorization code the provider gives back. |
| state | string <= 256 characters The state the service gave to the provider, compared with its cookie. |
| error | string <= 256 characters The error the provider gives back when the person refused or the sign-in failed. |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}The answer is 202 whether the address has an account or not, and whether the link leaves or not. An address receives at most 5 links per quarter of an hour. The link lives 10 minutes and serves once.
| email required | string <email> <= 254 characters |
| return_to | string <= 512 characters ^/([A-Za-z0-9_.~-][A-Za-z0-9/_.~?=&%-]*)?$ |
{- "return_to": "string"
}{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}| token required | string <password> ^[A-Za-z0-9_-]{43}$ |
| Set-Cookie | string The session cookie. |
required | object (Person) |
required | Array of objects (Membership) |
{- "token": "pa$$word"
}{- "person": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
}, - "memberships": [
- {
- "organization": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "plan": "free"
}, - "role": "viewer",
- "joined_at": "2019-08-24T14:15:22Z"
}
]
}The signed-in person, their sessions, their organizations and the invitations they accept. The admin API serves them.
required | object (Person) |
required | Array of objects (Membership) |
{- "person": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
}, - "memberships": [
- {
- "organization": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "plan": "free"
}, - "role": "viewer",
- "joined_at": "2019-08-24T14:15:22Z"
}
]
}A null name removes the name. The other members of their organizations then see their email address.
| name | string or null [ 1 .. 256 ] characters |
required | object (Person) |
required | Array of objects (Membership) |
{- "name": "string"
}{- "person": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
}, - "memberships": [
- {
- "organization": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "plan": "free"
}, - "role": "viewer",
- "joined_at": "2019-08-24T14:15:22Z"
}
]
}| name required | string [ 1 .. 128 ] characters |
required | object (OrganizationSummary) |
| role required | string (Role) Enum: "viewer" "member" "admin" viewer reads. member also writes the agents, their keys, permissions and budgets, the rules, the approval groups and the incident response. admin also manages the people, the admin keys, the plan and the settings of the organization. |
| joined_at required | string <date-time> |
{- "name": "string"
}{- "organization": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "plan": "free"
}, - "role": "viewer",
- "joined_at": "2019-08-24T14:15:22Z"
}The verified email of the person must be the invited email.
| token required | string <password> ^[A-Za-z0-9_-]{43}$ |
required | object (OrganizationSummary) |
| role required | string (Role) Enum: "viewer" "member" "admin" viewer reads. member also writes the agents, their keys, permissions and budgets, the rules, the approval groups and the incident response. admin also manages the people, the admin keys, the plan and the settings of the organization. |
| joined_at required | string <date-time> |
{- "token": "pa$$word"
}{- "organization": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "plan": "free"
}, - "role": "viewer",
- "joined_at": "2019-08-24T14:15:22Z"
}The settings of the organization, its people, its invitations and its admin keys. The admin API serves them.
| id required | string <uuid> |
| name required | string |
| plan required | string (PlanID) Enum: "free" "starter" "scale" "business" |
required | object (IncidentContacts) Who receives the incidents of the organization. |
| approval_expires_in required | integer <int32> (ExpiresIn) [ 60 .. 86400 ] Seconds before a wait expires without an answer. |
| approval_on_expiry required | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| audience required | string The audience a platform writes in the tokens it signs for the agents of the organization, https://api.paidwen.com/organizations/ followed by the identifier of the organization. |
| created_at required | string <date-time> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "plan": "free",
- "approval_expires_in": 60,
- "approval_on_expiry": "deny",
- "audience": "string",
- "created_at": "2019-08-24T14:15:22Z"
}| name | string [ 1 .. 128 ] characters |
object | |
| approval_expires_in | integer <int32> (ExpiresIn) [ 60 .. 86400 ] Seconds before a wait expires without an answer. |
| approval_on_expiry | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| id required | string <uuid> |
| name required | string |
| plan required | string (PlanID) Enum: "free" "starter" "scale" "business" |
required | object (IncidentContacts) Who receives the incidents of the organization. |
| approval_expires_in required | integer <int32> (ExpiresIn) [ 60 .. 86400 ] Seconds before a wait expires without an answer. |
| approval_on_expiry required | string (OnExpiry) Enum: "deny" "allow" What happens when no answer comes before the deadline. deny refuses the action, allow lets it run. |
| audience required | string The audience a platform writes in the tokens it signs for the agents of the organization, https://api.paidwen.com/organizations/ followed by the identifier of the organization. |
| created_at required | string <date-time> |
{- "name": "string",
- "approval_expires_in": 60,
- "approval_on_expiry": "deny"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "plan": "free",
- "approval_expires_in": 60,
- "approval_on_expiry": "deny",
- "audience": "string",
- "created_at": "2019-08-24T14:15:22Z"
}| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (Member) |
| has_more required | boolean |
{- "data": [
- {
- "person": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
}, - "role": "viewer",
- "joined_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}The organization always keeps one admin at least, so demoting the last one answers 409.
| person_id required | string <uuid> |
| role required | string (Role) Enum: "viewer" "member" "admin" viewer reads. member also writes the agents, their keys, permissions and budgets, the rules, the approval groups and the incident response. admin also manages the people, the admin keys, the plan and the settings of the organization. |
required | object (Person) |
| role required | string (Role) Enum: "viewer" "member" "admin" viewer reads. member also writes the agents, their keys, permissions and budgets, the rules, the approval groups and the incident response. admin also manages the people, the admin keys, the plan and the settings of the organization. |
| joined_at required | string <date-time> |
{- "role": "viewer"
}{- "person": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
}, - "role": "viewer",
- "joined_at": "2019-08-24T14:15:22Z"
}The person loses the organization at their next call. A person may always leave. Removing the last admin answers 409.
| person_id required | string <uuid> |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (Invitation) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "role": "viewer",
- "invited_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}The invitation leaves by email, with a link that lives 7 days and serves once. A person already in the organization, or an address already invited, answers 409.
| email required | string <email> <= 254 characters |
| role required | string (Role) Enum: "viewer" "member" "admin" viewer reads. member also writes the agents, their keys, permissions and budgets, the rules, the approval groups and the incident response. admin also manages the people, the admin keys, the plan and the settings of the organization. |
| id required | string <uuid> |
| email required | string <email> |
| role required | string (Role) Enum: "viewer" "member" "admin" viewer reads. member also writes the agents, their keys, permissions and budgets, the rules, the approval groups and the incident response. admin also manages the people, the admin keys, the plan and the settings of the organization. |
| invited_by | string The email of the person, or the redacted admin key, that invited. |
| created_at required | string <date-time> |
| expires_at required | string <date-time> |
{- "role": "viewer"
}{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "role": "viewer",
- "invited_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}| invitation_id required | string <uuid> |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}| limit | integer <int32> [ 1 .. 100 ] Default: 10 The number of items in the page, from 1 to 100. |
| starting_after | string <uuid> The identifier of the last item of the previous page. |
required | Array of objects (AdminKey) |
| has_more required | boolean |
{- "data": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "redacted": "string",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z"
}
], - "has_more": true
}The response carries the key once, in secret.
| id required | string <uuid> |
| redacted required | string |
| created_by | string |
| created_at required | string <date-time> |
| revoked_at required | string or null <date-time> |
| secret required | string <password> The key itself, shown only in this response. |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "redacted": "string",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "revoked_at": "2019-08-24T14:15:22Z",
- "secret": "pa$$word"
}The key stops working at once. Revoking a revoked key succeeds again.
| key_id required | string <uuid> |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}The plan of the organization, its usage, the cap of its invoice, and the payment by card through the seller of record. The admin API serves them.
| plan required | string (PlanID) Enum: "free" "starter" "scale" "business" |
object (Subscription) | |
required | object (Usage) The events of the organization this month, as the decision point counts them. |
| trial_eligible required | boolean The organization never had a subscription, so a plan with a free trial opens with its trial. During a trial, the subscription has the status trialing and current_period_end is the end of the trial. A trial bills nothing, events beyond the included ones included, and stops at the included events, as the free plan stops at its limit. |
| invoice_cap_usd | number <double> The most a month may cost, set by the organization. |
{- "plan": "free",
- "subscription": {
- "status": "active",
- "interval": "month",
- "paddle_customer_id": "string",
- "current_period_start": "2019-08-24T14:15:22Z",
- "current_period_end": "2019-08-24T14:15:22Z",
- "cancel_at": "2019-08-24T14:15:22Z"
}, - "usage": {
- "month": "string",
- "events": 0,
- "included": 0,
- "limit": 0,
- "stopped": true
}, - "trial_eligible": true,
- "invoice_cap_usd": 0.1
}The cap bounds what a month costs: the price of the plan and the events beyond the included ones. At the cap, the decision point answers 503 until the next month. Only Scale and Business take a cap, at least the price of a month of their plan.
| invoice_cap_usd | number or null <double> ( 0 .. 100000000 ] |
| plan required | string (PlanID) Enum: "free" "starter" "scale" "business" |
object (Subscription) | |
required | object (Usage) The events of the organization this month, as the decision point counts them. |
| trial_eligible required | boolean The organization never had a subscription, so a plan with a free trial opens with its trial. During a trial, the subscription has the status trialing and current_period_end is the end of the trial. A trial bills nothing, events beyond the included ones included, and stops at the included events, as the free plan stops at its limit. |
| invoice_cap_usd | number <double> The most a month may cost, set by the organization. |
{- "invoice_cap_usd": 1
}{- "plan": "free",
- "subscription": {
- "status": "active",
- "interval": "month",
- "paddle_customer_id": "string",
- "current_period_start": "2019-08-24T14:15:22Z",
- "current_period_end": "2019-08-24T14:15:22Z",
- "cancel_at": "2019-08-24T14:15:22Z"
}, - "usage": {
- "month": "string",
- "events": 0,
- "included": 0,
- "limit": 0,
- "stopped": true
}, - "trial_eligible": true,
- "invoice_cap_usd": 0.1
}Creates the transaction at the seller of record, and gives what the dashboard needs to open its checkout. The plan opens only when the seller confirms the payment, by its webhook or by the synchronization that follows the checkout. An organization that already pays answers 409 and changes its plan instead. A plan with trial_days in contracts/plans.json opens with its free trial when trial_eligible is true: the card is taken at the checkout and charged at the end of the trial.
| plan required | string Enum: "starter" "scale" "business" |
| interval required | string (BillingInterval) Enum: "month" "year" |
| transaction_id required | string |
| environment required | string Enum: "sandbox" "production" |
| client_token required | string The client-side token of Paddle.js, which only opens checkouts. |
{- "plan": "starter",
- "interval": "month"
}{- "transaction_id": "string",
- "environment": "sandbox",
- "client_token": "string"
}The dashboard calls it when the checkout says the payment completed. It applies the same state as the webhook, read from the seller and never from the browser.
| transaction_id required | string^txn_[a-z0-9]{26}$ |
| plan required | string (PlanID) Enum: "free" "starter" "scale" "business" |
object (Subscription) | |
required | object (Usage) The events of the organization this month, as the decision point counts them. |
| trial_eligible required | boolean The organization never had a subscription, so a plan with a free trial opens with its trial. During a trial, the subscription has the status trialing and current_period_end is the end of the trial. A trial bills nothing, events beyond the included ones included, and stops at the included events, as the free plan stops at its limit. |
| invoice_cap_usd | number <double> The most a month may cost, set by the organization. |
{- "transaction_id": "string"
}{- "plan": "free",
- "subscription": {
- "status": "active",
- "interval": "month",
- "paddle_customer_id": "string",
- "current_period_start": "2019-08-24T14:15:22Z",
- "current_period_end": "2019-08-24T14:15:22Z",
- "cancel_at": "2019-08-24T14:15:22Z"
}, - "usage": {
- "month": "string",
- "events": 0,
- "included": 0,
- "limit": 0,
- "stopped": true
}, - "trial_eligible": true,
- "invoice_cap_usd": 0.1
}Going back to the free plan cancels the subscription instead. A subscription with a scheduled cancellation answers 409, and changes its plan once resumed. During a free trial, the change keeps the trial and bills nothing until its end.
| plan required | string Enum: "starter" "scale" "business" |
| interval required | string (BillingInterval) Enum: "month" "year" |
| plan required | string (PlanID) Enum: "free" "starter" "scale" "business" |
object (Subscription) | |
required | object (Usage) The events of the organization this month, as the decision point counts them. |
| trial_eligible required | boolean The organization never had a subscription, so a plan with a free trial opens with its trial. During a trial, the subscription has the status trialing and current_period_end is the end of the trial. A trial bills nothing, events beyond the included ones included, and stops at the included events, as the free plan stops at its limit. |
| invoice_cap_usd | number <double> The most a month may cost, set by the organization. |
{- "plan": "starter",
- "interval": "month"
}{- "plan": "free",
- "subscription": {
- "status": "active",
- "interval": "month",
- "paddle_customer_id": "string",
- "current_period_start": "2019-08-24T14:15:22Z",
- "current_period_end": "2019-08-24T14:15:22Z",
- "cancel_at": "2019-08-24T14:15:22Z"
}, - "usage": {
- "month": "string",
- "events": 0,
- "included": 0,
- "limit": 0,
- "stopped": true
}, - "trial_eligible": true,
- "invoice_cap_usd": 0.1
}Paddle computes the amounts on the subscription, with the same proration as the change. An organization without an active subscription, a subscription with a scheduled cancellation, or a request for its current plan and interval, answers 409. During a free trial, the change keeps the trial and bills nothing until its end. The credit of a downgrade pays the next payments, so the amount taken at next_payment is next_payment.amount minus the credit, and never less than zero.
| plan required | string Enum: "starter" "scale" "business" |
| interval required | string (BillingInterval) Enum: "month" "year" |
| plan required | string Enum: "starter" "scale" "business" |
| interval required | string (BillingInterval) Enum: "month" "year" |
| currency_code required | string^[A-Z]{3}$ The currency of the subscription, such as USD. |
| due_now required | number <double> >= 0 The amount charged right away for the rest of the current period. |
| credit required | number <double> >= 0 The amount credited to the subscription for the unused part of the current plan, used on the next payments. |
required | object |
{- "plan": "starter",
- "interval": "month"
}{- "plan": "starter",
- "interval": "month",
- "currency_code": "string",
- "due_now": 0,
- "credit": 0,
- "next_payment": {
- "amount": 0,
- "at": "2019-08-24T14:15:22Z"
}
}The plan stays until the end of the period, then the organization goes back to the free plan.
| plan required | string (PlanID) Enum: "free" "starter" "scale" "business" |
object (Subscription) | |
required | object (Usage) The events of the organization this month, as the decision point counts them. |
| trial_eligible required | boolean The organization never had a subscription, so a plan with a free trial opens with its trial. During a trial, the subscription has the status trialing and current_period_end is the end of the trial. A trial bills nothing, events beyond the included ones included, and stops at the included events, as the free plan stops at its limit. |
| invoice_cap_usd | number <double> The most a month may cost, set by the organization. |
{- "plan": "free",
- "subscription": {
- "status": "active",
- "interval": "month",
- "paddle_customer_id": "string",
- "current_period_start": "2019-08-24T14:15:22Z",
- "current_period_end": "2019-08-24T14:15:22Z",
- "cancel_at": "2019-08-24T14:15:22Z"
}, - "usage": {
- "month": "string",
- "events": 0,
- "included": 0,
- "limit": 0,
- "stopped": true
}, - "trial_eligible": true,
- "invoice_cap_usd": 0.1
}| plan required | string (PlanID) Enum: "free" "starter" "scale" "business" |
object (Subscription) | |
required | object (Usage) The events of the organization this month, as the decision point counts them. |
| trial_eligible required | boolean The organization never had a subscription, so a plan with a free trial opens with its trial. During a trial, the subscription has the status trialing and current_period_end is the end of the trial. A trial bills nothing, events beyond the included ones included, and stops at the included events, as the free plan stops at its limit. |
| invoice_cap_usd | number <double> The most a month may cost, set by the organization. |
{- "plan": "free",
- "subscription": {
- "status": "active",
- "interval": "month",
- "paddle_customer_id": "string",
- "current_period_start": "2019-08-24T14:15:22Z",
- "current_period_end": "2019-08-24T14:15:22Z",
- "cancel_at": "2019-08-24T14:15:22Z"
}, - "usage": {
- "month": "string",
- "events": 0,
- "included": 0,
- "limit": 0,
- "stopped": true
}, - "trial_eligible": true,
- "invoice_cap_usd": 0.1
}The Paddle-Signature header must carry a valid HMAC-SHA256 of the body with the secret of the notification destination. The same event sent again changes nothing. Any answer other than 2xx makes Paddle send the event again.
| Paddle-Signature required | string <= 1024 characters The signature of the event, ts= |
| property name* additional property | any |
{ }{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}| connected required | boolean |
| team_id | string |
| team_name | string |
| connected_at | string <date-time> |
{- "connected": true,
- "team_id": "string",
- "team_name": "string",
- "connected_at": "2019-08-24T14:15:22Z"
}The browser comes from the Add to Slack button of the dashboard, so the organization travels in the query. The person must be an admin of it.
| organization required | string <uuid> The organization the Slack workspace joins. |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}Checks the state against the cookie and the session, exchanges the code with oauth.v2.access, seals the token of the bot, connects the workspace, then sends the browser back to the dashboard.
| code | string <= 2048 characters The authorization code the provider gives back. |
| state | string <= 256 characters The state the service gave to the provider, compared with its cookie. |
| error | string <= 256 characters The error the provider gives back when the person refused or the sign-in failed. |
{- "type": "string",
- "title": "string",
- "status": 0,
- "detail": "string",
- "instance": "string"
}