{
  "openapi": "3.1.0",
  "info": {
    "title": "Motor API",
    "version": "2026-10-22",
    "description": "Motor's identity and billing layer: users, teams, members, keys, sessions, agents, usage, and invoices. The conventions of every Motor API are at https://new.motor.dev/docs."
  },
  "servers": [
    {
      "url": "https://new.motor.dev"
    }
  ],
  "security": [
    {
      "bearer": []
    },
    {
      "dpop": []
    }
  ],
  "tags": [
    {
      "name": "Users",
      "description": "The person of a key."
    },
    {
      "name": "Teams",
      "description": "A team owns work, and its billing account pays for it. Each user can have a personal team. Every team has a card, so people make teams in the console, where they add the card."
    },
    {
      "name": "Members",
      "description": "The people of a team, and the invitations to join it."
    },
    {
      "name": "Agents",
      "description": "Agents contribute to a team, with scopes, and with tokens that last at most 4 hours."
    },
    {
      "name": "Sessions",
      "description": "Session keys last 24 hours. `motor auth` gets one with the person's approval in the browser; a user key mints one."
    },
    {
      "name": "Keys",
      "description": "User keys last until they expire, for automation. Only a user key manages them."
    },
    {
      "name": "Billing",
      "description": "What a team used, and its invoices."
    }
  ],
  "paths": {
    "/api/user": {
      "get": {
        "operationId": "get_user",
        "summary": "Get the user",
        "description": "Returns the user of the session key or the user key.",
        "tags": [
          "Users"
        ],
        "responses": {
          "200": {
            "description": "The user.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                },
                "example": {
                  "id": "user_1BbA6sXxyUWHYvKqN5T3dM",
                  "name": "Ada Lovelace",
                  "email": "ada@example.com",
                  "created_at": "2026-09-01T09:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/teams": {
      "get": {
        "operationId": "list_teams",
        "summary": "List the teams",
        "description": "Returns the teams of the user, the personal team first; for an agent, its team. Needs `team:read` for an agent.",
        "tags": [
          "Teams"
        ],
        "responses": {
          "200": {
            "description": "The teams.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TeamPage"
                },
                "example": {
                  "data": [
                    {
                      "id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                      "name": "Lighthouse",
                      "personal": false,
                      "role": "admin",
                      "standing": "active",
                      "spending_limit_cents": 50000,
                      "card": {
                        "brand": "visa",
                        "last4": "4242",
                        "exp_month": 12,
                        "exp_year": 2030
                      },
                      "created_at": "2026-10-01T09:00:00.000Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/teams/{team_id}": {
      "get": {
        "operationId": "get_team",
        "summary": "Get a team",
        "description": "Returns a team of the user, or the agent's team. Needs `team:read` for an agent.",
        "tags": [
          "Teams"
        ],
        "responses": {
          "200": {
            "description": "The team.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Team"
                },
                "example": {
                  "id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                  "name": "Lighthouse",
                  "personal": false,
                  "role": "admin",
                  "standing": "active",
                  "spending_limit_cents": 50000,
                  "card": {
                    "brand": "visa",
                    "last4": "4242",
                    "exp_month": 12,
                    "exp_year": 2030
                  },
                  "created_at": "2026-10-01T09:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          }
        ]
      },
      "patch": {
        "operationId": "update_team",
        "summary": "Change a team",
        "description": "Changes a team's handle or spending limit. Only an admin can. A `spending_limit_cents` of null removes the limit.",
        "tags": [
          "Teams"
        ],
        "responses": {
          "200": {
            "description": "The team.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Team"
                },
                "example": {
                  "id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                  "name": "Lighthouse",
                  "personal": false,
                  "role": "admin",
                  "standing": "active",
                  "spending_limit_cents": 50000,
                  "card": {
                    "brand": "visa",
                    "last4": "4242",
                    "exp_month": 12,
                    "exp_year": 2030
                  },
                  "created_at": "2026-10-01T09:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The team's new handle."
                  },
                  "spending_limit_cents": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 0,
                    "description": "The most that the team may spend in a month, in cents, or null for no limit."
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {
                "spending_limit_cents": 50000
              }
            }
          }
        }
      }
    },
    "/api/teams/{team_id}/members": {
      "get": {
        "operationId": "list_members",
        "summary": "List the members",
        "description": "Returns the members of a team. Needs `team:read` for an agent.",
        "tags": [
          "Members"
        ],
        "responses": {
          "200": {
            "description": "The members.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberPage"
                },
                "example": {
                  "data": [
                    {
                      "user": {
                        "id": "user_1BbA6sXxyUWHYvKqN5T3dM",
                        "name": "Ada Lovelace",
                        "email": "ada@example.com",
                        "created_at": "2026-09-01T09:00:00.000Z"
                      },
                      "role": "admin",
                      "joined_at": "2026-10-01T09:00:00.000Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          }
        ]
      }
    },
    "/api/teams/{team_id}/members/{user_id}": {
      "patch": {
        "operationId": "update_member",
        "summary": "Change a member's role",
        "description": "Makes a member an admin or a member. Only an admin can, and a team keeps at least one admin.",
        "tags": [
          "Members"
        ],
        "responses": {
          "200": {
            "description": "The member.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Member"
                },
                "example": {
                  "user": {
                    "id": "user_1BbA6sXxyUWHYvKqN5T3dM",
                    "name": "Ada Lovelace",
                    "email": "ada@example.com",
                    "created_at": "2026-09-01T09:00:00.000Z"
                  },
                  "role": "member",
                  "joined_at": "2026-10-01T09:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          },
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "The member's user ID.",
            "schema": {
              "type": "string",
              "pattern": "^user_"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "member"
                    ]
                  }
                },
                "required": [
                  "role"
                ],
                "additionalProperties": false
              },
              "example": {
                "role": "member"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "remove_member",
        "summary": "Remove a member",
        "description": "Removes a member from a team: an admin can remove anyone, and a user can leave. The member's agents in the team are deregistered. Nobody can leave their personal team.",
        "tags": [
          "Members"
        ],
        "responses": {
          "204": {
            "description": "Done. There is no body."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          },
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "The member's user ID.",
            "schema": {
              "type": "string",
              "pattern": "^user_"
            }
          }
        ]
      }
    },
    "/api/teams/{team_id}/invites": {
      "get": {
        "operationId": "list_invites",
        "summary": "List the invitations",
        "description": "Returns the open invitations of a team.",
        "tags": [
          "Members"
        ],
        "responses": {
          "200": {
            "description": "The invitations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvitePage"
                },
                "example": {
                  "data": [
                    {
                      "id": "invite_1BbA6sXxyUWHYvKqN5T3dM",
                      "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                      "email": "grace@example.com",
                      "role": "member",
                      "created_at": "2026-10-22T09:00:00.000Z",
                      "expires_at": "2026-10-29T09:00:00.000Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          }
        ]
      },
      "post": {
        "operationId": "create_invite",
        "summary": "Invite someone",
        "description": "Emails an invitation to join the team, with a link that lasts 7 days. Only an admin can. An invitation to the same email replaces the last one.",
        "tags": [
          "Members"
        ],
        "responses": {
          "201": {
            "description": "The invitation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invite"
                },
                "example": {
                  "id": "invite_1BbA6sXxyUWHYvKqN5T3dM",
                  "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                  "email": "grace@example.com",
                  "role": "member",
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-29T09:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "Where the invitation goes."
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "member"
                    ],
                    "description": "The role in the team: `member` if you don't say."
                  }
                },
                "required": [
                  "email"
                ],
                "additionalProperties": false
              },
              "example": {
                "email": "grace@example.com",
                "role": "member"
              }
            }
          }
        }
      }
    },
    "/api/teams/{team_id}/invites/{invite_id}": {
      "delete": {
        "operationId": "delete_invite",
        "summary": "Cancel an invitation",
        "description": "Cancels an invitation; its link stops working. Only an admin can.",
        "tags": [
          "Members"
        ],
        "responses": {
          "204": {
            "description": "Done. There is no body."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          },
          {
            "name": "invite_id",
            "in": "path",
            "required": true,
            "description": "The invitation's ID.",
            "schema": {
              "type": "string",
              "pattern": "^invite_"
            }
          }
        ]
      }
    },
    "/api/teams/{team_id}/usage": {
      "get": {
        "operationId": "get_usage",
        "summary": "Get the usage",
        "description": "Returns what the team used in a month, by meter, and what it costs. Needs `usage:read` for an agent.",
        "tags": [
          "Billing"
        ],
        "responses": {
          "200": {
            "description": "The usage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                },
                "example": {
                  "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                  "month": "2026-10",
                  "lines": [
                    {
                      "meter": "bytes_in",
                      "quantity": "2500000000",
                      "unit": "bytes",
                      "priced_quantity": "2.500000",
                      "priced_unit": "GB",
                      "amount_cents": 13
                    }
                  ],
                  "subtotal_cents": 13,
                  "allowance_cents": 0,
                  "credit_cents": 0,
                  "total_cents": 13
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          },
          {
            "name": "month",
            "in": "query",
            "required": false,
            "description": "The month, such as `2026-10`. The current month if you don't say.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{4}-[0-9]{2}$"
            }
          }
        ]
      }
    },
    "/api/teams/{team_id}/invoices": {
      "get": {
        "operationId": "list_invoices",
        "summary": "List the invoices",
        "description": "Returns the team's invoices, newest first.",
        "tags": [
          "Billing"
        ],
        "responses": {
          "200": {
            "description": "The invoices.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicePage"
                },
                "example": {
                  "data": [
                    {
                      "id": "invoice_1BbA6sXxyUWHYvKqN5T3dM",
                      "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                      "month": "2026-09",
                      "status": "paid",
                      "subtotal_cents": 1840,
                      "allowance_cents": 0,
                      "credit_cents": 0,
                      "total_cents": 1840,
                      "hosted_url": "https://invoice.stripe.com/i/acct_x/in_x",
                      "created_at": "2026-10-01T03:00:00.000Z",
                      "paid_at": "2026-10-01T04:00:00.000Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/TeamID"
          }
        ]
      }
    },
    "/api/keys": {
      "get": {
        "operationId": "list_keys",
        "summary": "List the user keys",
        "description": "Returns the user's user keys. Only a user key can.",
        "tags": [
          "Keys"
        ],
        "responses": {
          "200": {
            "description": "The keys.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyPage"
                },
                "example": {
                  "data": [
                    {
                      "id": "key_1BbA6sXxyUWHYvKqN5T3dM",
                      "kind": "user",
                      "name": "CI",
                      "hint": "motor_uk_…z9Y8",
                      "status": "active",
                      "created_via": "console",
                      "bound": false,
                      "created_at": "2026-10-22T09:00:00.000Z",
                      "expires_at": "2027-01-20T09:00:00.000Z",
                      "used_at": null,
                      "revoked_at": null
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/keys/{key_id}": {
      "get": {
        "operationId": "get_key",
        "summary": "Get a user key",
        "description": "Returns one of the user's user keys. Only a user key can.",
        "tags": [
          "Keys"
        ],
        "responses": {
          "200": {
            "description": "The key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Key"
                },
                "example": {
                  "id": "key_1BbA6sXxyUWHYvKqN5T3dM",
                  "kind": "user",
                  "name": "CI",
                  "hint": "motor_uk_…z9Y8",
                  "status": "active",
                  "created_via": "console",
                  "bound": false,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "used_at": null,
                  "revoked_at": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "description": "The key's ID.",
            "schema": {
              "type": "string",
              "pattern": "^key_"
            }
          }
        ]
      },
      "delete": {
        "operationId": "revoke_key",
        "summary": "Revoke a user key",
        "description": "Revokes a user key, and the session keys that it minted. Their agents are deregistered. Only a user key can.",
        "tags": [
          "Keys"
        ],
        "responses": {
          "200": {
            "description": "The key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Key"
                },
                "example": {
                  "id": "key_1BbA6sXxyUWHYvKqN5T3dM",
                  "kind": "user",
                  "name": "CI",
                  "hint": "motor_uk_…z9Y8",
                  "status": "revoked",
                  "created_via": "console",
                  "bound": false,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "used_at": null,
                  "revoked_at": "2026-10-22T10:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "description": "The key's ID.",
            "schema": {
              "type": "string",
              "pattern": "^key_"
            }
          }
        ]
      }
    },
    "/api/sessions": {
      "post": {
        "operationId": "create_session",
        "summary": "Mint a session key",
        "description": "Mints a session key, which lasts 24 hours, with a user key, such as in CI. A `DPoP` header with a proof binds the session key to the proof's key.",
        "tags": [
          "Sessions"
        ],
        "responses": {
          "201": {
            "description": "The session key, with `token`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Key"
                },
                "example": {
                  "id": "key_1BbA6sXxyUWHYvKqN5T3dM",
                  "kind": "session",
                  "name": "CI run",
                  "hint": "motor_sk_…a1B2",
                  "status": "active",
                  "created_via": "api",
                  "bound": false,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "used_at": null,
                  "revoked_at": null,
                  "token": "motor_sk_9fJ2kL3mN4pQ5rS6tU7vW8xY9zA0bC1d"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "A name for the session: the user key's name if you don't say."
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {
                "name": "CI run"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "list_sessions",
        "summary": "List the session keys",
        "description": "Returns the user's session keys that work now.",
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "The session keys.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyPage"
                },
                "example": {
                  "data": [
                    {
                      "id": "key_1BbA6sXxyUWHYvKqN5T3dM",
                      "kind": "session",
                      "name": "motor on ada-macbook",
                      "hint": "motor_sk_…a1B2",
                      "status": "active",
                      "created_via": "browser",
                      "bound": true,
                      "created_at": "2026-10-22T09:00:00.000Z",
                      "expires_at": "2026-10-23T09:00:00.000Z",
                      "used_at": null,
                      "revoked_at": null
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/sessions/{session_id}": {
      "get": {
        "operationId": "get_session",
        "summary": "Get a session key",
        "description": "Returns one of the user's session keys.",
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "The session key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Key"
                },
                "example": {
                  "id": "key_1BbA6sXxyUWHYvKqN5T3dM",
                  "kind": "session",
                  "name": "motor on ada-macbook",
                  "hint": "motor_sk_…a1B2",
                  "status": "active",
                  "created_via": "browser",
                  "bound": true,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "used_at": null,
                  "revoked_at": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "The session key's ID.",
            "schema": {
              "type": "string",
              "pattern": "^key_"
            }
          }
        ]
      },
      "delete": {
        "operationId": "end_session",
        "summary": "Revoke a session key",
        "description": "Revokes a session key, and deregisters its agents. A session key can revoke itself, which is how the CLI signs out; a user key can revoke any of its user's session keys.",
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "The session key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Key"
                },
                "example": {
                  "id": "key_1BbA6sXxyUWHYvKqN5T3dM",
                  "kind": "session",
                  "name": "motor on ada-macbook",
                  "hint": "motor_sk_…a1B2",
                  "status": "revoked",
                  "created_via": "browser",
                  "bound": true,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "used_at": null,
                  "revoked_at": "2026-10-22T10:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "The session key's ID.",
            "schema": {
              "type": "string",
              "pattern": "^key_"
            }
          }
        ]
      }
    },
    "/api/sessions/device_authorizations": {
      "post": {
        "operationId": "start_device_authorization",
        "summary": "Start a device sign-in",
        "description": "Starts the sign-in of a computer without a browser (RFC 8628), which `motor auth --device` uses. The person types `user_code` at `verification_uri` and approves with a passkey; meanwhile, the CLI polls `exchange_session` with `device_code`. A `DPoP` header names the device key that the session key will be bound to. Each address may make 30 of these requests a minute.",
        "tags": [
          "Sessions"
        ],
        "responses": {
          "201": {
            "description": "The codes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "device_code": {
                      "type": "string",
                      "description": "The secret that the CLI polls with."
                    },
                    "user_code": {
                      "type": "string",
                      "description": "The code that the person types, such as `WDJB-MJHT`."
                    },
                    "verification_uri": {
                      "type": "string",
                      "description": "Where the person types the code."
                    },
                    "verification_uri_complete": {
                      "type": "string",
                      "description": "The same page, with the code."
                    },
                    "expires_in": {
                      "type": "integer",
                      "description": "Seconds until the codes expire."
                    },
                    "interval": {
                      "type": "integer",
                      "description": "The least seconds between two polls."
                    }
                  },
                  "required": [
                    "device_code",
                    "user_code",
                    "verification_uri",
                    "verification_uri_complete",
                    "expires_in",
                    "interval"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "device_code": "Kq3mN4pQ5rS6tU7vW8xY9zA0bC1d2E3f",
                  "user_code": "WDJB-MJHT",
                  "verification_uri": "https://new.motor.dev/activate",
                  "verification_uri_complete": "https://new.motor.dev/activate?user_code=WDJB-MJHT",
                  "expires_in": 600,
                  "interval": 5
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_name": {
                    "type": "string",
                    "description": "A name for the computer, such as `motor on build-server`."
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {
                "client_name": "motor on build-server"
              }
            }
          }
        },
        "security": []
      }
    },
    "/api/sessions/exchange": {
      "post": {
        "operationId": "exchange_session",
        "summary": "Get the session key of a sign-in",
        "description": "Trades the code of a browser sign-in, with its PKCE verifier, or an approved device code, for a session key. A `DPoP` header binds the session key to the proof's key; the key must be the one that the sign-in named. Until the person approves a device code, the answer is `authorization_pending`, or `slow_down` for a poll that comes too soon.",
        "tags": [
          "Sessions"
        ],
        "responses": {
          "201": {
            "description": "The session key, with `token`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Key"
                },
                "example": {
                  "id": "key_1BbA6sXxyUWHYvKqN5T3dM",
                  "kind": "session",
                  "name": "motor on ada-macbook",
                  "hint": "motor_sk_…a1B2",
                  "status": "active",
                  "created_via": "browser",
                  "bound": true,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "used_at": null,
                  "revoked_at": null,
                  "token": "motor_sk_9fJ2kL3mN4pQ5rS6tU7vW8xY9zA0bC1d"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "authorization_code",
                      "device_code"
                    ]
                  },
                  "code": {
                    "type": "string",
                    "description": "The code of a browser sign-in."
                  },
                  "code_verifier": {
                    "type": "string",
                    "description": "The PKCE verifier of the code's challenge."
                  },
                  "redirect_uri": {
                    "type": "string",
                    "description": "The loopback URL of the browser sign-in."
                  },
                  "device_code": {
                    "type": "string",
                    "description": "The device code of a device sign-in."
                  }
                },
                "required": [
                  "grant_type"
                ],
                "additionalProperties": false
              },
              "example": {
                "grant_type": "device_code",
                "device_code": "Kq3mN4pQ5rS6tU7vW8xY9zA0bC1d2E3f"
              }
            }
          }
        },
        "security": []
      }
    },
    "/api/agents": {
      "post": {
        "operationId": "start_agent",
        "summary": "Register an agent",
        "description": "Registers an agent in a team and generates its first token. Motor shows the token once; it lasts at most 4 hours and can be renewed. Registration lasts 24 hours by default, up to 30 days. Renewing a token does not extend the registration. A session key registers an agent in a team of its user; an agent token with the scope `agents:start` registers a sub-agent in its own team, with scopes, a lifetime, and a spending limit no greater than its own. The team must have a card.",
        "tags": [
          "Agents"
        ],
        "responses": {
          "201": {
            "description": "The agent, with `token`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Agent"
                },
                "example": {
                  "id": "agent_1BbA6sXxyUWHYvKqN5T3dM",
                  "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                  "parent_id": null,
                  "name": "reviewer",
                  "status": "running",
                  "scopes": [
                    "current:*"
                  ],
                  "user_id": "user_1BbA6sXxyUWHYvKqN5T3dM",
                  "spending_limit_cents": 2000,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "ended_at": null,
                  "used_at": null,
                  "token": {
                    "id": "token_1BbA6sXxyUWHYvKqN5T3dM",
                    "token": "motor_tk_9fJ2kL3mN4pQ5rS6tU7vW8xY9zA0bC1d",
                    "expires_at": "2026-10-22T13:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/BillingRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "team_id": {
                    "type": "string",
                    "description": "The agent's team. A sub-agent is in its parent's team, so the field is optional for an agent token."
                  },
                  "name": {
                    "type": "string",
                    "description": "The agent's name, at most 100 characters."
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "What the agent may do, such as `current:write`, `current:*`, or `*`."
                  },
                  "expires_in": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 2592000,
                    "description": "The agent's lifetime in seconds: 24 hours, or the parent's end, if you don't say."
                  },
                  "token_expires_in": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 14400,
                    "description": "The first token's lifetime in seconds: 4 hours if you don't say."
                  },
                  "spending_limit_cents": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 0,
                    "description": "The most that the agent may spend in a month, in cents."
                  }
                },
                "required": [
                  "name",
                  "scopes"
                ],
                "additionalProperties": false
              },
              "example": {
                "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                "name": "reviewer",
                "scopes": [
                  "current:*"
                ],
                "spending_limit_cents": 2000
              }
            }
          }
        }
      },
      "get": {
        "operationId": "list_agents",
        "summary": "List the agents",
        "description": "Returns a team's agents, newest first: those with active registrations, or all of them.",
        "tags": [
          "Agents"
        ],
        "responses": {
          "200": {
            "description": "The agents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentPage"
                },
                "example": {
                  "data": [
                    {
                      "id": "agent_1BbA6sXxyUWHYvKqN5T3dM",
                      "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                      "parent_id": null,
                      "name": "reviewer",
                      "status": "running",
                      "scopes": [
                        "current:*"
                      ],
                      "user_id": "user_1BbA6sXxyUWHYvKqN5T3dM",
                      "spending_limit_cents": 2000,
                      "created_at": "2026-10-22T09:00:00.000Z",
                      "expires_at": "2026-10-23T09:00:00.000Z",
                      "ended_at": null,
                      "used_at": null
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          }
        },
        "parameters": [
          {
            "name": "team_id",
            "in": "query",
            "required": true,
            "description": "The team's ID.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "`running` for active registrations (the default), or `all` to include deregistered and expired agents.",
            "schema": {
              "type": "string",
              "enum": [
                "running",
                "all"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ]
      }
    },
    "/api/agents/{agent_id}": {
      "get": {
        "operationId": "get_agent",
        "summary": "Get an agent",
        "description": "Returns an agent: one of the user's teams, the agent itself, or one of its descendants.",
        "tags": [
          "Agents"
        ],
        "responses": {
          "200": {
            "description": "The agent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Agent"
                },
                "example": {
                  "id": "agent_1BbA6sXxyUWHYvKqN5T3dM",
                  "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                  "parent_id": null,
                  "name": "reviewer",
                  "status": "running",
                  "scopes": [
                    "current:*"
                  ],
                  "user_id": "user_1BbA6sXxyUWHYvKqN5T3dM",
                  "spending_limit_cents": 2000,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "ended_at": null,
                  "used_at": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The agent's ID.",
            "schema": {
              "type": "string",
              "pattern": "^agent_"
            }
          }
        ]
      },
      "delete": {
        "operationId": "end_agent",
        "summary": "Deregister an agent",
        "description": "Deregisters an agent and its sub-agents, and revokes their tokens. An agent can deregister itself and its descendants; a user, the agents that they registered; an admin, any agent of the team.",
        "tags": [
          "Agents"
        ],
        "responses": {
          "200": {
            "description": "The agent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Agent"
                },
                "example": {
                  "id": "agent_1BbA6sXxyUWHYvKqN5T3dM",
                  "team_id": "team_1BbA6sXxyUWHYvKqN5T3dM",
                  "parent_id": null,
                  "name": "reviewer",
                  "status": "ended",
                  "scopes": [
                    "current:*"
                  ],
                  "user_id": "user_1BbA6sXxyUWHYvKqN5T3dM",
                  "spending_limit_cents": 2000,
                  "created_at": "2026-10-22T09:00:00.000Z",
                  "expires_at": "2026-10-23T09:00:00.000Z",
                  "ended_at": "2026-10-22T10:00:00.000Z",
                  "used_at": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The agent's ID.",
            "schema": {
              "type": "string",
              "pattern": "^agent_"
            }
          }
        ]
      }
    },
    "/api/agents/{agent_id}/tokens": {
      "post": {
        "operationId": "issue_agent_token",
        "summary": "Renew an agent's token",
        "description": "Gives a registered agent a new token, which lasts at most 4 hours, without extending its registration. Previous tokens keep working until they expire. A session key of the user who registered the agent, or of a team admin, can; so can an ancestor agent with `agents:start`. An agent can't renew its own token.",
        "tags": [
          "Agents"
        ],
        "responses": {
          "201": {
            "description": "The token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentToken"
                },
                "example": {
                  "id": "token_1BbA6sXxyUWHYvKqN5T3dM",
                  "token": "motor_tk_9fJ2kL3mN4pQ5rS6tU7vW8xY9zA0bC1d",
                  "expires_at": "2026-10-22T13:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/InvalidField"
          }
        },
        "parameters": [
          {
            "name": "agent_id",
            "in": "path",
            "required": true,
            "description": "The agent's ID.",
            "schema": {
              "type": "string",
              "pattern": "^agent_"
            }
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "expires_in": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 14400,
                    "description": "The token's lifetime in seconds: 4 hours if you don't say."
                  }
                },
                "required": [],
                "additionalProperties": false
              },
              "example": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "A session key (`motor_sk_`), a user key (`motor_uk_`), or an agent token (`motor_tk_`)."
      },
      "dpop": {
        "type": "http",
        "scheme": "DPoP",
        "description": "A session key that is bound to a device key, with a `DPoP` header that holds a proof of the device key (RFC 9449)."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "A key, 1 to 128 printable characters, that makes the request happen once: for 24 hours, the same key and request get the first answer again.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        }
      },
      "TeamID": {
        "name": "team_id",
        "in": "path",
        "required": true,
        "description": "The team's ID.",
        "schema": {
          "type": "string",
          "pattern": "^team_"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "The most items in the page, from 1 to 100. 50 if you don't say.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "The `next_cursor` of the last page.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The body isn't a JSON object, or the request can't go on.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "invalid_json",
                "message": "The body isn't a JSON object: unexpected EOF.",
                "retryable": false
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "The credential is missing, unknown, revoked, or expired, or a bound session key has no valid DPoP proof.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "unauthorized",
                "message": "The credential is unknown, revoked, or expired.",
                "retryable": false
              }
            }
          }
        }
      },
      "BillingRequired": {
        "description": "The team needs a card before it can do billable work.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "billing_required",
                "message": "The team needs a card before it can do billable work.",
                "retryable": false
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "The credential can't do this.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "forbidden",
                "message": "Your credential can't do this.",
                "retryable": false
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "There is no such resource, or the credential can't see it.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "not_found",
                "message": "There is no such resource, or you can't see it.",
                "retryable": false
              }
            }
          }
        }
      },
      "Conflict": {
        "description": "The state of things doesn't allow the request, or an Idempotency-Key was used with another request.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "conflict",
                "message": "A team needs an admin. Make another member an admin first.",
                "retryable": false
              }
            }
          }
        }
      },
      "InvalidField": {
        "description": "A field or a parameter has a value that Motor can't accept.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "invalid_field",
                "message": "`name` is required.",
                "retryable": false
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "The credential made more than 600 requests in a minute.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "rate_limited",
                "message": "Too many requests: the limit is 600 a minute.",
                "retryable": true
              }
            }
          }
        }
      }
    },
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The user's ID."
          },
          "name": {
            "type": "string",
            "description": "The user's name."
          },
          "email": {
            "type": "string",
            "description": "The email of the user's Google account."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "email",
          "created_at"
        ],
        "additionalProperties": false,
        "title": "User"
      },
      "Card": {
        "type": "object",
        "properties": {
          "brand": {
            "type": "string",
            "description": "The card's brand, such as `visa`."
          },
          "last4": {
            "type": "string",
            "description": "The last 4 digits."
          },
          "exp_month": {
            "type": "integer"
          },
          "exp_year": {
            "type": "integer"
          }
        },
        "required": [
          "brand",
          "last4",
          "exp_month",
          "exp_year"
        ],
        "additionalProperties": false,
        "title": "Card"
      },
      "Team": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The team's ID."
          },
          "name": {
            "type": "string",
            "description": "The team's handle."
          },
          "personal": {
            "type": "boolean",
            "description": "Whether the team is a user's personal team, which gets $10 a month for free."
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "member",
              "contributor"
            ],
            "description": "The caller's role: `contributor` for an agent."
          },
          "standing": {
            "type": "string",
            "enum": [
              "active",
              "billing_required",
              "over_limit",
              "suspended"
            ],
            "description": "Whether the team may use the services now."
          },
          "spending_limit_cents": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The most that the team may spend in a month, or null for no limit."
          },
          "card": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Card"
              },
              {
                "type": "null"
              }
            ],
            "description": "The card that pays the team's invoices, or null."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "personal",
          "role",
          "standing",
          "spending_limit_cents",
          "card",
          "created_at"
        ],
        "additionalProperties": false,
        "title": "Team"
      },
      "Member": {
        "type": "object",
        "properties": {
          "user": {
            "$ref": "#/components/schemas/User"
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "member"
            ]
          },
          "joined_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "user",
          "role",
          "joined_at"
        ],
        "additionalProperties": false,
        "title": "Member"
      },
      "Invite": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The invitation's ID."
          },
          "team_id": {
            "type": "string",
            "description": "The team's ID."
          },
          "email": {
            "type": "string",
            "description": "The email that Motor sent the invitation to."
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "member"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "team_id",
          "email",
          "role",
          "created_at",
          "expires_at"
        ],
        "additionalProperties": false,
        "title": "Invite"
      },
      "Key": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The key's ID."
          },
          "kind": {
            "type": "string",
            "enum": [
              "user",
              "session"
            ],
            "description": "A user key or a session key."
          },
          "name": {
            "type": "string",
            "description": "The key's name: for a session key, the computer that asked for it."
          },
          "hint": {
            "type": "string",
            "description": "The key, with all but its last 4 characters hidden."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "expired",
              "revoked"
            ]
          },
          "created_via": {
            "type": "string",
            "enum": [
              "console",
              "browser",
              "device",
              "api"
            ],
            "description": "How the key came to be."
          },
          "bound": {
            "type": "boolean",
            "description": "Whether the key is bound to a device key, and needs a DPoP proof with each request."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the key expires, or null for a user key that never does."
          },
          "used_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "revoked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "token": {
            "type": "string",
            "description": "The key itself. Only the response that makes the key has it; Motor shows it once."
          }
        },
        "required": [
          "id",
          "kind",
          "name",
          "hint",
          "status",
          "created_via",
          "bound",
          "created_at",
          "expires_at",
          "used_at",
          "revoked_at"
        ],
        "additionalProperties": false,
        "title": "Key"
      },
      "AgentToken": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The token's ID."
          },
          "token": {
            "type": "string",
            "description": "The token itself (`motor_tk_…`). Motor shows it once."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the token expires: at most 4 hours after it's made, and no later than the agent's registration expiry."
          }
        },
        "required": [
          "id",
          "token",
          "expires_at"
        ],
        "additionalProperties": false,
        "title": "AgentToken"
      },
      "Agent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The agent's ID."
          },
          "team_id": {
            "type": "string",
            "description": "The agent's team."
          },
          "parent_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The agent that registered this one, or null."
          },
          "name": {
            "type": "string",
            "description": "The agent's name."
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "ended",
              "expired"
            ]
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "What the agent may do (see the docs about scopes)."
          },
          "user_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The user who registered the agent's lineage."
          },
          "spending_limit_cents": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The most that the agent may spend in a month, or null for no limit of its own."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the registration expires, unless the agent is deregistered sooner."
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "used_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "token": {
            "$ref": "#/components/schemas/AgentToken"
          }
        },
        "required": [
          "id",
          "team_id",
          "parent_id",
          "name",
          "status",
          "scopes",
          "user_id",
          "spending_limit_cents",
          "created_at",
          "expires_at",
          "ended_at",
          "used_at"
        ],
        "additionalProperties": false,
        "title": "Agent"
      },
      "UsageLine": {
        "type": "object",
        "properties": {
          "meter": {
            "type": "string",
            "enum": [
              "bytes_in",
              "bytes_out",
              "bytes_stored",
              "compute",
              "memory"
            ]
          },
          "quantity": {
            "type": "string",
            "description": "The amount in the meter's base unit, as a string, because it can pass 2^53."
          },
          "unit": {
            "type": "string",
            "description": "The base unit, such as `bytes` or `vCPU-milliseconds`."
          },
          "priced_quantity": {
            "type": "string",
            "description": "The amount in the priced unit, such as GB, with 6 decimals."
          },
          "priced_unit": {
            "type": "string",
            "description": "The unit of the price, such as `GB` or `vCPU-hour`."
          },
          "amount_cents": {
            "type": "integer",
            "description": "The cost, rounded to the cent."
          }
        },
        "required": [
          "meter",
          "quantity",
          "unit",
          "priced_quantity",
          "priced_unit",
          "amount_cents"
        ],
        "additionalProperties": false,
        "title": "UsageLine"
      },
      "Usage": {
        "type": "object",
        "properties": {
          "team_id": {
            "type": "string",
            "description": "The team's ID."
          },
          "month": {
            "type": "string",
            "description": "The month, such as `2026-10`."
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsageLine"
            }
          },
          "subtotal_cents": {
            "type": "integer"
          },
          "allowance_cents": {
            "type": "integer",
            "description": "The free allocation of a personal team."
          },
          "credit_cents": {
            "type": "integer"
          },
          "total_cents": {
            "type": "integer",
            "description": "What the team owes for the month, so far for the current month."
          }
        },
        "required": [
          "team_id",
          "month",
          "lines",
          "subtotal_cents",
          "allowance_cents",
          "credit_cents",
          "total_cents"
        ],
        "additionalProperties": false,
        "title": "Usage"
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The invoice's ID."
          },
          "team_id": {
            "type": "string",
            "description": "The team's ID."
          },
          "month": {
            "type": "string",
            "description": "The month, such as `2026-09`."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "open",
              "paid",
              "failed",
              "empty",
              "void"
            ]
          },
          "subtotal_cents": {
            "type": "integer"
          },
          "allowance_cents": {
            "type": "integer"
          },
          "credit_cents": {
            "type": "integer"
          },
          "total_cents": {
            "type": "integer"
          },
          "hosted_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stripe's page of the invoice, where it can be paid."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "team_id",
          "month",
          "status",
          "subtotal_cents",
          "allowance_cents",
          "credit_cents",
          "total_cents",
          "hosted_url",
          "created_at",
          "paid_at"
        ],
        "additionalProperties": false,
        "title": "Invoice"
      },
      "TeamPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Team"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "The cursor of the next page, or null on the last page."
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "MemberPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Member"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "The cursor of the next page, or null on the last page."
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "InvitePage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Invite"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "The cursor of the next page, or null on the last page."
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "KeyPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Key"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "The cursor of the next page, or null on the last page."
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "AgentPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Agent"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "The cursor of the next page, or null on the last page."
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "InvoicePage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Invoice"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "The cursor of the next page, or null on the last page."
          }
        },
        "required": [
          "data",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "What went wrong, for programs, such as `invalid_field`."
              },
              "message": {
                "type": "string",
                "description": "What went wrong, for people."
              },
              "field": {
                "type": "string",
                "description": "The field with the problem, for `invalid_field`."
              },
              "retryable": {
                "type": "boolean",
                "description": "Whether the same request can succeed later."
              },
              "retry_after_seconds": {
                "type": "integer",
                "description": "How long to wait before a retry."
              }
            },
            "required": [
              "code",
              "message",
              "retryable"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false,
        "title": "Error"
      }
    }
  }
}
