Paidwen API (0.20.0)

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.

decisions

The question an agent asks before each action, and the wait for a human answer. The decision point serves them.

Ask whether an agent may perform an action.

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.

Authorizations:
agentKey
Request Body schema: application/json
required
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)

Responses

Response Headers
Idempotent-Replayed
string
Value: "true"

Present with the value true when the decision was given before for the same action identifier.

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "tool": {
    },
  • "params": { },
  • "cost": {
    },
  • "context": {
    }
}

Response samples

Content type
application/json
{
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "agent_id": "string",
  • "verdict": "allow",
  • "rule_id": "string",
  • "rule_name": "string",
  • "observed": [
    ],
  • "permission": {
    },
  • "budget": {
    },
  • "approval": {
    },
  • "incident": {
    },
  • "decided_at": "2019-08-24T14:15:22Z"
}

Poll the wait for a human answer, following the poll mode of OpenID CIBA.

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.

Authorizations:
agentKey
path Parameters
approval_id
required
string <uuid>

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "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"
}

traces

The spans the SDK sends to the journal, in the OTLP format of OpenTelemetry. The decision point serves them.

Send spans to the journal, in the OTLP/HTTP format of OpenTelemetry.

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.

Authorizations:
agentKey
Request Body schema:
required
string <binary>

Responses

Response Schema:
string <binary>

Request samples

Content type
No sample

Response samples

Content type
No sample

metrics

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.

Send metrics, in the OTLP/HTTP format of OpenTelemetry, so that the spending they carry reaches the budget and the journal.

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.

Authorizations:
agentKey
Request Body schema:
required
string <binary>

Responses

Response Schema:
string <binary>

Request samples

Content type
No sample

Response samples

Content type
No sample

caller

The agent that a key or an agent token identifies. The decision point serves it.

Read the agent that the key or the agent token identifies, like GetCallerIdentity of AWS STS.

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.

Authorizations:
agentKey

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  • "environment": "production",
  • "status": "active"
}

agents

The registry of the agents of the organization. The admin API serves it.

List the agents of the organization, in the order of their creation.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (Agent)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Declare an agent.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
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

Responses

Response Headers
Location
string

The address of the agent.

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "name": "string",
  • "owner": "[email protected]",
  • "team": "string",
  • "description": "string",
  • "model_provider": "string",
  • "environment": "production",
  • "risk_level": "low",
  • "labels": {
    },
  • "budget": {
    },
  • "record_content": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "owner": "string",
  • "team": "string",
  • "description": "string",
  • "model_provider": "string",
  • "environment": "production",
  • "risk_level": "low",
  • "labels": {
    },
  • "budget": {
    },
  • "record_content": true,
  • "status": "active",
  • "spent": {
    },
  • "risk": {
    },
  • "trust_rule_id": "bc0189b6-423c-45bc-a15f-d23762319a0c",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Read an agent.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>

Responses

Response Schema: application/json
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>

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "owner": "string",
  • "team": "string",
  • "description": "string",
  • "model_provider": "string",
  • "environment": "production",
  • "risk_level": "low",
  • "labels": {
    },
  • "budget": {
    },
  • "record_content": true,
  • "status": "active",
  • "spent": {
    },
  • "risk": {
    },
  • "trust_rule_id": "bc0189b6-423c-45bc-a15f-d23762319a0c",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Change an agent, following JSON Merge Patch.

An absent field does not change. A field set to null is removed. The environment of an agent never changes.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
Request Body schema: application/merge-patch+json
required
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

Responses

Response Schema: application/json
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>

Request samples

Content type
application/merge-patch+json
{
  • "name": "string",
  • "owner": "[email protected]",
  • "team": "string",
  • "description": "string",
  • "model_provider": "string",
  • "risk_level": "low",
  • "labels": {
    },
  • "budget": {
    },
  • "record_content": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "owner": "string",
  • "team": "string",
  • "description": "string",
  • "model_provider": "string",
  • "environment": "production",
  • "risk_level": "low",
  • "labels": {
    },
  • "budget": {
    },
  • "record_content": true,
  • "status": "active",
  • "spent": {
    },
  • "risk": {
    },
  • "trust_rule_id": "bc0189b6-423c-45bc-a15f-d23762319a0c",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Remove an agent with its keys and its permissions.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

teams

The teams of the organization, which group its agents. The admin API serves them.

List the teams of the organization, in the order of their handles.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (Team)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Create a team. Its handle never changes, and the rules compare it.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
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

Responses

Response Headers
Location
string

The address of the team.

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "handle": "string",
  • "name": "string"
}

Response samples

Content type
application/json
{
  • "handle": "string",
  • "name": "string",
  • "agents": 0,
  • "created_at": "2019-08-24T14:15:22Z"
}

Read a team.

Authorizations:
adminKey(sessionorganization)
path Parameters
handle
required
string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$

The handle of a team, which never changes, for example customer-support.

Responses

Response Schema: application/json
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>

Response samples

Content type
application/json
{
  • "handle": "string",
  • "name": "string",
  • "agents": 0,
  • "created_at": "2019-08-24T14:15:22Z"
}

Rename a team, following JSON Merge Patch. The handle stays.

Authorizations:
adminKey(sessionorganization)
path Parameters
handle
required
string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$

The handle of a team, which never changes, for example customer-support.

Request Body schema: application/merge-patch+json
required
name
string [ 1 .. 128 ] characters

Responses

Response Schema: application/json
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>

Request samples

Content type
application/merge-patch+json
{
  • "name": "string"
}

Response samples

Content type
application/json
{
  • "handle": "string",
  • "name": "string",
  • "agents": 0,
  • "created_at": "2019-08-24T14:15:22Z"
}

Remove a team that holds no agent.

Authorizations:
adminKey(sessionorganization)
path Parameters
handle
required
string (TeamHandle) <= 64 characters ^[a-z0-9]+(-[a-z0-9]+)*$

The handle of a team, which never changes, for example customer-support.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

keys

The keys of an agent. The admin API serves them.

List the active and revoked keys of an agent, in the order of their creation.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (AgentKey)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Give the agent a new key.

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.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "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"
}

Revoke a key of the agent.

The key stops working within one second. Revoking a revoked key succeeds again.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
key_id
required
string <uuid>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

trust-rules

The trust rules of the organization, which turn the tokens a platform signs into agents. The admin API serves them.

List the trust rules of the organization, in the order of their creation.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (TrustRule)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Write a trust rule.

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.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
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

Responses

Response Headers
Location
string

The address of the trust rule.

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "name": "string",
  • "issuer": "string",
  • "jwks": {
    },
  • "condition": "string",
  • "agent_name": "string",
  • "environment": "production",
  • "team": "string",
  • "owner": "[email protected]",
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "issuer": "string",
  • "jwks": {
    },
  • "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"
}

Read a trust rule.

Authorizations:
adminKey(sessionorganization)
path Parameters
trust_rule_id
required
string <uuid>

Responses

Response Schema: application/json
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>

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "issuer": "string",
  • "jwks": {
    },
  • "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"
}

Change a trust rule, following JSON Merge Patch.

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.

Authorizations:
adminKey(sessionorganization)
path Parameters
trust_rule_id
required
string <uuid>
Request Body schema: application/merge-patch+json
required
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

Responses

Response Schema: application/json
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>

Request samples

Content type
application/merge-patch+json
{
  • "name": "string",
  • "issuer": "string",
  • "jwks": {
    },
  • "condition": "string",
  • "agent_name": "string",
  • "team": "string",
  • "owner": "[email protected]",
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "issuer": "string",
  • "jwks": {
    },
  • "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"
}

Remove a trust rule.

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.

Authorizations:
adminKey(sessionorganization)
path Parameters
trust_rule_id
required
string <uuid>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

oauth

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.

Exchange the token a platform signed for an agent token, following OAuth 2.0 Token Exchange, or a device code for the key of an agent, following the OAuth 2.0 Device Authorization Grant.

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.

Request Body schema: application/x-www-form-urlencoded
required
One of
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.

Responses

Response Headers
Cache-Control
string

Always no-store.

Response Schema: application/json
One of
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.

Response samples

Content type
application/json
Example
{
  • "access_token": "string",
  • "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  • "token_type": "Bearer",
  • "expires_in": 0
}

Start the sign-in of the Paidwen command on a device, following the OAuth 2.0 Device Authorization Grant.

The command receives a device code and a user code. It shows the user code and the verification address to the person, then polls POST /v1/oauth/token with the device code every interval seconds. The person opens the verification address in a browser, signs in, checks the user code and chooses the organization. The codes expire after 15 minutes. The service keeps only the SHA-256 digest of the device code. Follows RFC 8628.

Request Body schema: application/x-www-form-urlencoded
required
client_id
required
string (CommandClientID)
Value: "paidwen"

The client identifier of the Paidwen command, the only client of the device authorization grant.

scope
string

Ignored. RFC 8628 allows it, and the command always receives the key of the agent of the person.

Responses

Response Headers
Cache-Control
string

Always no-store.

Response Schema: application/json
device_code
required
string

The secret the command polls with. It never leaves the device.

user_code
required
string^[BCDFGHJKLMNPQRSTVWXZ]{4}-[BCDFGHJKLMNPQRSTV...

The code the person checks in the dashboard, eight consonants as RFC 8628 recommends, in two groups of four.

verification_uri
required
string

The address where the person enters the user code, https://app.paidwen.com/device in production.

verification_uri_complete
required
string

The same address with the user code, which the command opens in the browser.

expires_in
required
integer <int32>

The seconds before the codes expire.

interval
required
integer <int32>

The seconds to wait between two polls.

Response samples

Content type
application/json
{
  • "device_code": "string",
  • "user_code": "string",
  • "verification_uri": "string",
  • "verification_uri_complete": "string",
  • "expires_in": 0,
  • "interval": 0
}

devices

The sign-ins of the Paidwen command on a device, which a person accepts in the dashboard. The admin API serves them.

Read the sign-in of the Paidwen command that a user code names.

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.

Authorizations:
(sessionorganization)
path Parameters
user_code
required
string [ 8 .. 9 ] characters

The user code the Paidwen command shows, with or without its hyphen, in any case.

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "user_code": "string",
  • "status": "pending",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  • "agent_name": "string"
}

Accept or refuse the sign-in of the Paidwen command on a device.

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.

Authorizations:
(sessionorganization)
path Parameters
user_code
required
string [ 8 .. 9 ] characters

The user code the Paidwen command shows, with or without its hyphen, in any case.

Request Body schema: application/json
required
answer
required
string
Enum: "approve" "deny"

Responses

Response Schema: application/json
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.

Request samples

Content type
application/json
{
  • "answer": "approve"
}

Response samples

Content type
application/json
{
  • "user_code": "string",
  • "status": "pending",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  • "agent_name": "string"
}

permissions

What an agent may do and may not do. The admin API serves them.

Read what the agent may do and may not do.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "allow": [
    ],
  • "deny": [
    ]
}

Replace both lists of permissions of the agent.

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.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
Request Body schema: application/json
required
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.

Responses

Response Schema: application/json
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.

Request samples

Content type
application/json
{
  • "allow": [
    ],
  • "deny": [
    ]
}

Response samples

Content type
application/json
{
  • "allow": [
    ],
  • "deny": [
    ]
}

rules

The rules of the organization. The admin API serves them.

List the rules of the organization, in the order of the organization.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (Rule)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Write a rule.

The condition must compile and return a boolean, or the rule is refused.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
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.

Responses

Response Headers
Location
string

The address of the rule.

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "name": "string",
  • "condition": "string",
  • "verdict": "allow",
  • "mode": "active",
  • "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
  • "source_text": "string"
}

Response samples

Content type
application/json
{
  • "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"
}

Write a rule, permissions or a budget from a sentence, or check a rule written in CEL.

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.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
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.

Responses

Response Schema: application/json
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)

Request samples

Content type
application/json
{
  • "text": "string",
  • "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  • "rule": {
    }
}

Response samples

Content type
application/json
{
  • "kind": "rule",
  • "text": "string",
  • "rule": {
    },
  • "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  • "permissions": {
    },
  • "current_permissions": {
    },
  • "budget": {
    },
  • "reading": "string",
  • "complete": true,
  • "preview": {
    },
  • "warnings": [
    ]
}

Read a rule.

Authorizations:
adminKey(sessionorganization)
path Parameters
rule_id
required
string <uuid>

Responses

Response Schema: application/json
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>

Response samples

Content type
application/json
{
  • "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"
}

Change a rule, following JSON Merge Patch.

Setting mode to observe or active switches the rule, in both directions.

Authorizations:
adminKey(sessionorganization)
path Parameters
rule_id
required
string <uuid>
Request Body schema: application/merge-patch+json
required
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

Responses

Response Schema: application/json
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>

Request samples

Content type
application/merge-patch+json
{
  • "name": "string",
  • "condition": "string",
  • "verdict": "allow",
  • "mode": "active",
  • "approval_group_id": "7b1ecb30-2be8-411f-b261-fc1ace40e235",
  • "source_text": "string"
}

Response samples

Content type
application/json
{
  • "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"
}

Remove a rule.

Authorizations:
adminKey(sessionorganization)
path Parameters
rule_id
required
string <uuid>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

approval-groups

Who approves what, on which channel, and what happens without an answer. The admin API serves them.

List the approval groups of the organization, in the order of their creation.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (ApprovalGroup)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Declare who approves, on which channel, and what happens without an answer.

Naming a verdict in default_for makes the group the default group of that verdict, in place of the group that held it before.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
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"

Responses

Response Headers
Location
string

The address of the approval group.

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "name": "string",
  • "members": [],
  • "slack_channel": "string",
  • "teams_webhook_url": "pa$$word",
  • "expires_in": 60,
  • "on_expiry": "deny",
  • "default_for": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "members": [],
  • "slack_channel": "string",
  • "teams_webhook_host": "string",
  • "expires_in": 60,
  • "on_expiry": "deny",
  • "default_for": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Read an approval group.

Authorizations:
adminKey(sessionorganization)
path Parameters
group_id
required
string <uuid>

Responses

Response Schema: application/json
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>

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "members": [],
  • "slack_channel": "string",
  • "teams_webhook_host": "string",
  • "expires_in": 60,
  • "on_expiry": "deny",
  • "default_for": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Change an approval group, following JSON Merge Patch.

Authorizations:
adminKey(sessionorganization)
path Parameters
group_id
required
string <uuid>
Request Body schema: application/merge-patch+json
required
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"

Responses

Response Schema: application/json
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>

Request samples

Content type
application/merge-patch+json
{
  • "name": "string",
  • "members": [],
  • "slack_channel": "string",
  • "teams_webhook_url": "pa$$word",
  • "expires_in": 60,
  • "on_expiry": "deny",
  • "default_for": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "members": [],
  • "slack_channel": "string",
  • "teams_webhook_host": "string",
  • "expires_in": 60,
  • "on_expiry": "deny",
  • "default_for": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Remove an approval group that no rule names.

Authorizations:
adminKey(sessionorganization)
path Parameters
group_id
required
string <uuid>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

approvals

The actions that wait for a human answer, and the answers. The admin API serves them.

List the approvals of the organization, in the order of their creation.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (ApprovalRequest)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Read an action that waits or waited for a human answer.

The dashboard opens an approval by its identifier, for example from the buttons of the card that Microsoft Teams shows.

Authorizations:
adminKey(sessionorganization)
path Parameters
approval_id
required
string <uuid>

Responses

Response Schema: application/json
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>

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "agent": {
    },
  • "tool": {
    },
  • "params": { },
  • "cost": {
    },
  • "verdict": "require_approval",
  • "rule": {
    },
  • "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"
}

Approve or deny an action that waits for a human answer.

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.

Authorizations:
adminKey(sessionorganization)
path Parameters
approval_id
required
string <uuid>
Request Body schema: application/json
required
answer
required
string (ApprovalAnswerValue)
Enum: "approve" "deny"
comment
string [ 1 .. 1000 ] characters

Responses

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "answer": "approve",
  • "comment": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "agent": {
    },
  • "tool": {
    },
  • "params": { },
  • "cost": {
    },
  • "verdict": "require_approval",
  • "rule": {
    },
  • "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"
}

audit

Who did what, when, why, with which agent and with which permission, read from the journal. The admin API serves it.

Export the audit of the actions decided in a period, in JSON or in CSV.

The period runs from from, included, to to, excluded, and lasts at most 366 days. The audit is built from the journal only.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema:
Array
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.

Response samples

Content type
[
  • {
    }
]

Export the evidence pack of a framework for a period, as a signed ZIP file.

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.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Headers
Content-Disposition
string

The name of the file.

Response Schema: application/zip
string <binary>

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

List the public keys that sign the evidence packs.

The manifest of a pack names its key in key_id. A retired key stays in the list, so that its packs still verify.

Responses

Response Schema: application/json
required
Array of objects (EvidenceKey)

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Answer who did an action, when, why, with which agent and with which permission.

The record is built from the journal only, with the journal lines it comes from.

Authorizations:
adminKey(sessionorganization)
path Parameters
action_id
required
string <uuid>

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "agent": {
    },
  • "tool": {
    },
  • "params": { },
  • "cost": {
    },
  • "session_id": "string",
  • "decided_at": "2019-08-24T14:15:22Z",
  • "verdict": "allow",
  • "rule": {
    },
  • "observed": [
    ],
  • "permission": {
    },
  • "budget": {
    },
  • "approval": {
    },
  • "execution": {
    },
  • "incident": {
    },
  • "lines": [
    ]
}

incidents

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.

Put an agent in quarantine.

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.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
Request Body schema: application/json
optional
reason
string [ 1 .. 1000 ] characters

Why the gesture is made, kept in the incident and the journal.

Responses

Response Schema: application/json
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

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "agent": {
    },
  • "kind": "quarantine",
  • "state": "open",
  • "reason": "string",
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "keys_revoked": 0,
  • "opened_by": {
    },
  • "opened_at": "2019-08-24T14:15:22Z",
  • "lifted_by": {
    },
  • "lifted_at": "2019-08-24T14:15:22Z",
  • "lift_reason": "string"
}

Release an agent from quarantine.

An agent that is not in quarantine answers 409.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
Request Body schema: application/json
optional
reason
string [ 1 .. 1000 ] characters

Why the gesture is made, kept in the incident and the journal.

Responses

Response Schema: application/json
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

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "agent": {
    },
  • "kind": "quarantine",
  • "state": "open",
  • "reason": "string",
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "keys_revoked": 0,
  • "opened_by": {
    },
  • "opened_at": "2019-08-24T14:15:22Z",
  • "lifted_by": {
    },
  • "lifted_at": "2019-08-24T14:15:22Z",
  • "lift_reason": "string"
}

Disable an agent.

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.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
Request Body schema: application/json
optional
reason
string [ 1 .. 1000 ] characters

Why the gesture is made, kept in the incident and the journal.

Responses

Response Schema: application/json
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

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "agent": {
    },
  • "kind": "quarantine",
  • "state": "open",
  • "reason": "string",
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "keys_revoked": 0,
  • "opened_by": {
    },
  • "opened_at": "2019-08-24T14:15:22Z",
  • "lifted_by": {
    },
  • "lifted_at": "2019-08-24T14:15:22Z",
  • "lift_reason": "string"
}

Enable a disabled agent.

An agent that is not disabled answers 409.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
Request Body schema: application/json
optional
reason
string [ 1 .. 1000 ] characters

Why the gesture is made, kept in the incident and the journal.

Responses

Response Schema: application/json
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

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "agent": {
    },
  • "kind": "quarantine",
  • "state": "open",
  • "reason": "string",
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "keys_revoked": 0,
  • "opened_by": {
    },
  • "opened_at": "2019-08-24T14:15:22Z",
  • "lifted_by": {
    },
  • "lifted_at": "2019-08-24T14:15:22Z",
  • "lift_reason": "string"
}

Revoke every active key of an agent at once.

The agent signs in no more until it receives a new key.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
Request Body schema: application/json
optional
reason
string [ 1 .. 1000 ] characters

Why the gesture is made, kept in the incident and the journal.

Responses

Response Schema: application/json
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

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "agent": {
    },
  • "kind": "quarantine",
  • "state": "open",
  • "reason": "string",
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "keys_revoked": 0,
  • "opened_by": {
    },
  • "opened_at": "2019-08-24T14:15:22Z",
  • "lifted_by": {
    },
  • "lifted_at": "2019-08-24T14:15:22Z",
  • "lift_reason": "string"
}

Revoke every active key of an agent and give it a new key.

The response carries the new key once, in secret.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
Request Body schema: application/json
optional
reason
string [ 1 .. 1000 ] characters

Why the gesture is made, kept in the incident and the journal.

Responses

Response Schema: application/json
required
object (Incident)
required
object (CreatedAgentKey)

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "incident": {
    },
  • "key": {
    }
}

List the incidents of the organization, the most recent first.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (Incident)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Read an incident.

Authorizations:
adminKey(sessionorganization)
path Parameters
incident_id
required
string <uuid>

Responses

Response Schema: application/json
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

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "agent": {
    },
  • "kind": "quarantine",
  • "state": "open",
  • "reason": "string",
  • "action_id": "52d6fa12-2c88-46da-984a-4cc821c7837a",
  • "keys_revoked": 0,
  • "opened_by": {
    },
  • "opened_at": "2019-08-24T14:15:22Z",
  • "lifted_by": {
    },
  • "lifted_at": "2019-08-24T14:15:22Z",
  • "lift_reason": "string"
}

actions

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.

List the actions of the organization, the most recent first, read from the journal.

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.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (Action)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Read the costs per agent and per day of a period, read from the journal.

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.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "from": "2019-08-24T14:15:22Z",
  • "to": "2019-08-24T14:15:22Z",
  • "days": [
    ]
}

List the sessions of the agents, the most recent first, read from the journal.

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.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (AgentSession)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Read the steps of a session in the order of time, read from the journal.

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.

Authorizations:
adminKey(sessionorganization)
path Parameters
session_id
required
string [ 1 .. 256 ] characters
query Parameters
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.

Responses

Response Schema: application/json
session_id
required
string
required
Array of objects (SessionStep)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "session_id": "string",
  • "data": [
    ],
  • "has_more": true
}

Read who calls whom and which tools each agent touches in a period, read from the journal.

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.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "period_start": "2019-08-24T14:15:22Z",
  • "period_end": "2019-08-24T14:15:22Z",
  • "environment": "production",
  • "nodes": [
    ],
  • "edges": [
    ],
  • "hidden_agents": 0
}

Read what an agent did in a period, and what each rule did for it, read from the journal.

Authorizations:
adminKey(sessionorganization)
path Parameters
agent_id
required
string <uuid>
query Parameters
from
required
string <date-time>

The start of the period, included.

to
required
string <date-time>

The end of the period, excluded.

Responses

Response Schema: application/json
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>

Response samples

Content type
application/json
{
  • "from": "2019-08-24T14:15:22Z",
  • "to": "2019-08-24T14:15:22Z",
  • "verdicts": {
    },
  • "rules": [
    ],
  • "models_usd": 0.1,
  • "tools_usd": 0.1
}

auth

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.

Start signing in with Google, following OpenID Connect.

Keeps the PKCE verifier, the state and the nonce in a cookie for 10 minutes, then sends the browser to Google.

query Parameters
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.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

Finish signing in with Google.

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.

query Parameters
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.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

Start signing in with GitHub, following OAuth 2.0.

Keeps the PKCE verifier and the state in a cookie for 10 minutes, then sends the browser to GitHub.

query Parameters
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.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

Finish signing in with GitHub.

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.

query Parameters
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.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

account

The signed-in person, their sessions, their organizations and the invitations they accept. The admin API serves them.

Read the signed-in person and the organizations they belong to.

Authorizations:
session

Responses

Response Schema: application/json
required
object (Person)
required
Array of objects (Membership)

Response samples

Content type
application/json
{
  • "person": {},
  • "memberships": [
    ]
}

Change the name of the signed-in person, following JSON Merge Patch.

A null name removes the name. The other members of their organizations then see their email address.

Authorizations:
session
Request Body schema: application/merge-patch+json
required
name
string or null [ 1 .. 256 ] characters

Responses

Response Schema: application/json
required
object (Person)
required
Array of objects (Membership)

Request samples

Content type
application/merge-patch+json
{
  • "name": "string"
}

Response samples

Content type
application/json
{
  • "person": {},
  • "memberships": [
    ]
}

Close the session of the call.

Authorizations:
session

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

Close every session of the signed-in person.

Authorizations:
session

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

Create an organization, with the signed-in person as its admin, in the free plan.

Authorizations:
session
Request Body schema: application/json
required
name
required
string [ 1 .. 128 ] characters

Responses

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "name": "string"
}

Response samples

Content type
application/json
{
  • "organization": {
    },
  • "role": "viewer",
  • "joined_at": "2019-08-24T14:15:22Z"
}

Join an organization with the token of an invitation.

The verified email of the person must be the invited email.

Authorizations:
session
Request Body schema: application/json
required
token
required
string <password> ^[A-Za-z0-9_-]{43}$

Responses

Response Schema: application/json
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>

Request samples

Content type
application/json
{
  • "token": "pa$$word"
}

Response samples

Content type
application/json
{
  • "organization": {
    },
  • "role": "viewer",
  • "joined_at": "2019-08-24T14:15:22Z"
}

organization

The settings of the organization, its people, its invitations and its admin keys. The admin API serves them.

Read the settings of the organization.

Authorizations:
adminKey(sessionorganization)

Responses

Response Schema: application/json
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>

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "plan": "free",
  • "incident_contacts": {},
  • "approval_expires_in": 60,
  • "approval_on_expiry": "deny",
  • "audience": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Change the settings of the organization, following JSON Merge Patch.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/merge-patch+json
required
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.

Responses

Response Schema: application/json
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>

Request samples

Content type
application/merge-patch+json
{
  • "name": "string",
  • "incident_contacts": {},
  • "approval_expires_in": 60,
  • "approval_on_expiry": "deny"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "plan": "free",
  • "incident_contacts": {},
  • "approval_expires_in": 60,
  • "approval_on_expiry": "deny",
  • "audience": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

List the people of the organization, in the order of their arrival.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (Member)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Change the role of a person in the organization.

The organization always keeps one admin at least, so demoting the last one answers 409.

Authorizations:
adminKey(sessionorganization)
path Parameters
person_id
required
string <uuid>
Request Body schema: application/merge-patch+json
required
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.

Responses

Response Schema: application/json
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>

Request samples

Content type
application/merge-patch+json
{
  • "role": "viewer"
}

Response samples

Content type
application/json
{
  • "person": {},
  • "role": "viewer",
  • "joined_at": "2019-08-24T14:15:22Z"
}

Remove a person from the organization.

The person loses the organization at their next call. A person may always leave. Removing the last admin answers 409.

Authorizations:
adminKey(sessionorganization)
path Parameters
person_id
required
string <uuid>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

List the invitations of the organization that wait for an answer.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (Invitation)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Invite a person by email, with a role.

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.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
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.

Responses

Response Schema: application/json
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>

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "email": "[email protected]",
  • "role": "viewer",
  • "invited_by": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "expires_at": "2019-08-24T14:15:22Z"
}

Withdraw an invitation that waits for an answer.

Authorizations:
adminKey(sessionorganization)
path Parameters
invitation_id
required
string <uuid>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

List the active and revoked admin keys of the organization, in the order of their creation.

Authorizations:
adminKey(sessionorganization)
query Parameters
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.

Responses

Response Schema: application/json
required
Array of objects (AdminKey)
has_more
required
boolean

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "has_more": true
}

Create an admin key for the scripts of the organization.

The response carries the key once, in secret.

Authorizations:
adminKey(sessionorganization)

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "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"
}

Revoke an admin key.

The key stops working at once. Revoking a revoked key succeeds again.

Authorizations:
adminKey(sessionorganization)
path Parameters
key_id
required
string <uuid>

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

billing

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.

Read the plan of the organization, its subscription, its usage this month and the cap of its invoice.

Authorizations:
adminKey(sessionorganization)

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "plan": "free",
  • "subscription": {
    },
  • "usage": {
    },
  • "trial_eligible": true,
  • "invoice_cap_usd": 0.1
}

Set or remove the cap of the invoice, following JSON Merge Patch.

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.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/merge-patch+json
required
invoice_cap_usd
number or null <double> ( 0 .. 100000000 ]

Responses

Response Schema: application/json
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.

Request samples

Content type
application/merge-patch+json
{
  • "invoice_cap_usd": 1
}

Response samples

Content type
application/json
{
  • "plan": "free",
  • "subscription": {
    },
  • "usage": {
    },
  • "trial_eligible": true,
  • "invoice_cap_usd": 0.1
}

Prepare the payment by card of a paid plan.

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.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
plan
required
string
Enum: "starter" "scale" "business"
interval
required
string (BillingInterval)
Enum: "month" "year"

Responses

Response Schema: application/json
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.

Request samples

Content type
application/json
{
  • "plan": "starter",
  • "interval": "month"
}

Response samples

Content type
application/json
{
  • "transaction_id": "string",
  • "environment": "sandbox",
  • "client_token": "string"
}

Read a paid transaction and its subscription from the seller of record, and apply them.

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.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
transaction_id
required
string^txn_[a-z0-9]{26}$

Responses

Response Schema: application/json
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.

Request samples

Content type
application/json
{
  • "transaction_id": "string"
}

Response samples

Content type
application/json
{
  • "plan": "free",
  • "subscription": {
    },
  • "usage": {
    },
  • "trial_eligible": true,
  • "invoice_cap_usd": 0.1
}

Change the paid plan of the subscription, with a prorated charge or credit.

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.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
plan
required
string
Enum: "starter" "scale" "business"
interval
required
string (BillingInterval)
Enum: "month" "year"

Responses

Response Schema: application/json
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.

Request samples

Content type
application/json
{
  • "plan": "starter",
  • "interval": "month"
}

Response samples

Content type
application/json
{
  • "plan": "free",
  • "subscription": {
    },
  • "usage": {
    },
  • "trial_eligible": true,
  • "invoice_cap_usd": 0.1
}

Preview what a change of the paid plan charges or credits, without changing anything.

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.

Authorizations:
adminKey(sessionorganization)
Request Body schema: application/json
required
plan
required
string
Enum: "starter" "scale" "business"
interval
required
string (BillingInterval)
Enum: "month" "year"

Responses

Response Schema: application/json
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

Request samples

Content type
application/json
{
  • "plan": "starter",
  • "interval": "month"
}

Response samples

Content type
application/json
{
  • "plan": "starter",
  • "interval": "month",
  • "currency_code": "string",
  • "due_now": 0,
  • "credit": 0,
  • "next_payment": {
    }
}

Cancel the subscription at the end of its billing period.

The plan stays until the end of the period, then the organization goes back to the free plan.

Authorizations:
adminKey(sessionorganization)

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "plan": "free",
  • "subscription": {
    },
  • "usage": {
    },
  • "trial_eligible": true,
  • "invoice_cap_usd": 0.1
}

Remove a scheduled cancellation, so that the subscription renews.

Authorizations:
adminKey(sessionorganization)

Responses

Response Schema: application/json
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.

Response samples

Content type
application/json
{
  • "plan": "free",
  • "subscription": {
    },
  • "usage": {
    },
  • "trial_eligible": true,
  • "invoice_cap_usd": 0.1
}

Open the customer portal of the seller of record, to change the card and read the invoices.

Authorizations:
adminKey(sessionorganization)

Responses

Response Schema: application/json
url
required
string <uri>

Response samples

Content type
application/json

Receive an event of Paddle, the seller of record.

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.

header Parameters
Paddle-Signature
required
string <= 1024 characters

The signature of the event, ts=;h1=.

Request Body schema: application/json
required
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

slack

The Slack workspace connected to the organization. The admin API serves it.

Read the Slack workspace connected to the organization.

Authorizations:
adminKey(sessionorganization)

Responses

Response Schema: application/json
connected
required
boolean
team_id
string
team_name
string
connected_at
string <date-time>

Response samples

Content type
application/json
{
  • "connected": true,
  • "team_id": "string",
  • "team_name": "string",
  • "connected_at": "2019-08-24T14:15:22Z"
}

Disconnect the Slack workspace, and revoke the token of its bot.

Authorizations:
adminKey(sessionorganization)

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

Start adding Paidwen to a Slack workspace, following OAuth 2.0.

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.

Authorizations:
session
query Parameters
organization
required
string <uuid>

The organization the Slack workspace joins.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

Finish adding Paidwen to a Slack workspace.

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.

query Parameters
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.

Responses

Response samples

Content type
application/problem+json
{
  • "type": "string",
  • "title": "string",
  • "status": 0,
  • "detail": "string",
  • "instance": "string"
}

health

The state of the service. Both programs serve it.

Report that the service is up.

Responses

Response Schema: application/json
status
required
string
Value: "ok"

Response samples

Content type
application/json
{
  • "status": "ok"
}