CustomDomain Agents API

AI assistants acting for a workspace. An agent registers, a person approves what it may do in the console, and it works with a short lived token until the grant is revoked. The hosted MCP server accepts these tokens. The authorization server metadata (RFC 8414) and the signing keys (RFC 7517) are served on the API origin at `/.well-known/oauth-authorization-server` and `/.well-known/jwks.json`.

GitHub OpenAPI

Operations 9

POST /oauth/agent/register Register an agent as an OAuth client #
GET /oauth/agent/authorize Start an agent authorization (code with PKCE) #
POST /oauth/agent/token Exchange an authorization code or a refresh token for an access token #
POST /oauth/agent/revoke Revoke an agent's access with its refresh token #
GET /agent/consent-request/{id} Read a pending agent authorization, for the consent screen #
DELETE /agent/consent-request/{id} Deny a pending agent authorization #
POST /agent/consent Approve an agent and mint its authorization code #
GET /agent/grants List the workspace's agent grants #
DELETE /agent/grants/{id} Revoke an agent's access #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/customdomain-ai:customdomain-ai-agents-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

customdomain-ai-agents-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Customdomain Ai Agents API
  version: '1.0'
  license:
    name: Apache-2.0
    identifier: Apache-2.0
  description: 'Operations tagged Agents across 2 of this provider''s published API definitions: customdomain-ai-openapi-original.json, customdomain-ai-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.customdomain.ai/v1
  description: Hosted control-plane
- url: http://localhost:8080/v1
  description: Local control-plane
security:
- apiKey: []
tags:
- name: Agents
  description: AI assistants acting for a workspace. An agent registers, a person approves what it may do in the console, and it works with a short lived token until the grant is revoked. The hosted MCP server accepts these tokens. The authorization server metadata (RFC 8414) and the signing keys (RFC 7517) are served on the API origin at `/.well-known/oauth-authorization-server` and `/.well-known/jwks.json`.
paths:
  /oauth/agent/register:
    servers:
    - url: https://api.customdomain.ai
      description: Hosted control-plane (the origin, not /v1)
    post:
      operationId: registerAgentClient
      summary: Register an agent as an OAuth client
      tags:
      - Agents
      description: 'Dynamic Client Registration (RFC 7591). An AI assistant registers itself as a public client (PKCE, no secret) and can do nothing until a person approves a grant for it in the console. Registration is open on purpose, so it is bounded: a per-IP hourly budget on top of the global limit, and a client that nobody ever approves into a workspace is deleted after a while. Other client metadata (`client_uri`, `logo_uri`, `scope`, `contacts`, ...) is accepted and ignored. A `client_name` that claims a well known brand (Claude, ChatGPT, ...) is refused unless every redirect host belongs to that brand or is a loopback address. Errors use the RFC 7591 envelope.'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentClientRegistration'
      responses:
        '201':
          description: The registered client
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentClient'
        '400':
          description: '`invalid_client_metadata` (a bad or impersonating name, grant or response types without the authorization code grant) or `invalid_redirect_uri` (none, more than 10, a fragment, user information, or http on a host that is not loopback).'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '429':
          $ref: '#/components/responses/Error'
        '503':
          $ref: '#/components/responses/Error'
  /oauth/agent/authorize:
    servers:
    - url: https://api.customdomain.ai
      description: Hosted control-plane (the origin, not /v1)
    get:
      operationId: authorizeAgent
      summary: Start an agent authorization (code with PKCE)
      tags:
      - Agents
      description: The authorization endpoint. A browser is sent here by an agent; the request is validated (the client, the exact redirect URI, S256 PKCE, the scopes, the resource) and the browser is redirected to the console, where a signed in owner or admin sees what the agent asks for and where its code would go, and approves or denies. The authorization code goes to the redirect URI and is exchanged at `POST /oauth/agent/token`. A request with an unregistered or mismatched redirect URI is refused without redirecting. `client_id` is a registered client or an https URL of a Client ID Metadata Document.
      security: []
      parameters:
      - name: client_id
        in: query
        required: true
        schema:
          type: string
      - name: redirect_uri
        in: query
        required: true
        schema:
          type: string
          format: uri
      - name: response_type
        in: query
        required: true
        schema:
          type: string
          enum:
          - code
      - name: code_challenge
        in: query
        required: true
        description: BASE64URL(SHA-256(code_verifier)).
        schema:
          type: string
      - name: code_challenge_method
        in: query
        required: true
        schema:
          type: string
          enum:
          - S256
      - name: scope
        in: query
        required: true
        description: Space separated scopes from `domains:read`, `domains:connect`, `domains:disconnect` and `domains:purchase`. The person may approve fewer.
        schema:
          type: string
          example: domains:read domains:connect
      - name: state
        in: query
        required: false
        schema:
          type: string
      - name: resource
        in: query
        required: false
        description: 'RFC 8707. The resource the token is for: the MCP endpoint (`https://mcp.customdomain.ai/mcp`, the default) or this API''s origin. Anything else is `invalid_target`. The access token carries it as `aud`.'
        schema:
          type: string
          format: uri
      responses:
        '302':
          description: Redirect to the console consent screen
          headers:
            Location:
              schema:
                type: string
                format: uri
        '400':
          $ref: '#/components/responses/Error'
        '503':
          $ref: '#/components/responses/Error'
  /oauth/agent/token:
    servers:
    - url: https://api.customdomain.ai
      description: Hosted control-plane (the origin, not /v1)
    post:
      operationId: exchangeAgentToken
      summary: Exchange an authorization code or a refresh token for an access token
      tags:
      - Agents
      description: '`grant_type=authorization_code` (with the PKCE `code_verifier`) or `grant_type=refresh_token`. The access token is an ES256 JWT that lives 15 minutes and is verified locally against `/.well-known/jwks.json`; it carries the tenant, the application the grant is bound to, the grant, the scopes and `aud`. A refresh token rotates: every refresh returns a new one and retires the old, and presenting a retired one again revokes the whole grant (a client racing itself within ten seconds is only refused). Errors use the RFC 6749 envelope.'
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/AgentTokenRequest'
          application/json:
            schema:
              $ref: '#/components/schemas/AgentTokenRequest'
      responses:
        '200':
          description: The tokens
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentTokenResponse'
        '400':
          description: '`invalid_request`, `invalid_grant` (a code or refresh token that is invalid, expired, spent or revoked, a failed PKCE check, a grant that is no longer active), `invalid_target` (a resource that is not the one approved) or `unsupported_grant_type`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '503':
          description: Agent access is not enabled on this deployment (`temporarily_unavailable`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
  /oauth/agent/revoke:
    servers:
    - url: https://api.customdomain.ai
      description: Hosted control-plane (the origin, not /v1)
    post:
      operationId: revokeAgentToken
      summary: Revoke an agent's access with its refresh token
      tags:
      - Agents
      description: RFC 7009. Revokes the grant behind a refresh token, so the agent's access ends within one access token lifetime (15 minutes at most). It answers `200` for a token it does not know, so it cannot be used to find out which tokens exist. The workspace's owners and admins are told once.
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
              - token
              properties:
                token:
                  type: string
                  description: The refresh token.
          application/json:
            schema:
              type: object
              required:
              - token
              properties:
                token:
                  type: string
                  description: The refresh token.
      responses:
        '200':
          description: Revoked, or the token was not known
        '400':
          description: '`invalid_request`: no token.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '503':
          description: Agent access is not enabled on this deployment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
  /agent/consent-request/{id}:
    get:
      operationId: getAgentConsentRequest
      summary: Read a pending agent authorization, for the consent screen
      tags:
      - Agents
      description: 'What the console shows a signed in owner before they approve an agent: the client''s name, where its authorization code would go (`redirect_host`), whether that destination is a known assistant''s own (`verified`, `verified_as`) or the person''s own computer (`local`), whether the name imitates a brand it does not belong to (`imitates`; such a request cannot be approved), how the client identified itself, and the scopes asked for. The unguessable request id is the capability: it needs no other credential and reveals only this.'
      security: []
      parameters:
      - $ref: '#/components/parameters/Id'
      responses:
        '200':
          description: The pending request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentConsentRequest'
        '404':
          $ref: '#/components/responses/Error'
        '503':
          $ref: '#/components/responses/Error'
    delete:
      operationId: cancelAgentConsentRequest
      summary: Deny a pending agent authorization
      tags:
      - Agents
      description: 'Consumes the request so it can no longer be approved, from this tab or any other. Idempotent, and like the read it needs no credential: the request id is the capability, and cancelling is all it allows.'
      security: []
      parameters:
      - $ref: '#/components/parameters/Id'
      responses:
        '204':
          description: Denied
        '503':
          $ref: '#/components/responses/Error'
    servers:
    - url: https://api.customdomain.ai/v1
      description: Hosted control-plane
    - url: http://localhost:8080/v1
      description: Local control-plane
  /agent/consent:
    post:
      operationId: approveAgent
      summary: Approve an agent and mint its authorization code
      tags:
      - Agents
      description: 'Called by the console''s server after a person signs in and approves, with that member''s tenant API key (a widget token is refused, because it lives in browsers). The key''s member needs `agent:manage` (owners and admins), and `member_id` must belong to the workspace. The approved scopes are a subset of what was requested. The grant is bound to one `application_id` of the workspace. An agent whose code goes to an unverified host needs `acknowledged_unverified: true`, and one whose name imitates a brand is refused (`403`). `domains:purchase` also needs a `spend_cap_cents` and a saved card. Persistent access is the default; `persist: false` ends it after `expires_days`. The authorization code is single use and is exchanged at `POST /oauth/agent/token`.'
      security:
      - apiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentConsentApproval'
      responses:
        '200':
          description: The redirect for the agent, with its code
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentConsentResult'
        '400':
          $ref: '#/components/responses/Error'
        '401':
          $ref: '#/components/responses/Error'
        '403':
          $ref: '#/components/responses/Error'
        '409':
          $ref: '#/components/responses/Error'
        '503':
          $ref: '#/components/responses/Error'
    servers:
    - url: https://api.customdomain.ai/v1
      description: Hosted control-plane
    - url: http://localhost:8080/v1
      description: Local control-plane
  /agent/grants:
    get:
      operationId: listAgentGrants
      summary: List the workspace's agent grants
      tags:
      - Agents
      description: Every grant of the workspace with the current month's spend, for the console's manage screen. Needs a tenant API key held by an owner or admin (`agent:manage`). Refresh tokens are never returned.
      security:
      - apiKey: []
      responses:
        '200':
          description: The grants
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentGrantList'
        '401':
          $ref: '#/components/responses/Error'
        '403':
          $ref: '#/components/responses/Error'
        '503':
          $ref: '#/components/responses/Error'
    servers:
    - url: https://api.customdomain.ai/v1
      description: Hosted control-plane
    - url: http://localhost:8080/v1
      description: Local control-plane
  /agent/grants/{id}:
    delete:
      operationId: revokeAgentGrant
      summary: Revoke an agent's access
      tags:
      - Agents
      description: Ends the grant and kills its refresh tokens; the agent's access token stops working within its 15 minute life. A grant of another workspace answers `404`. The workspace's owners and admins are told once (a repeat is quiet), and the audit log records `agent.revoked`. Needs `agent:manage`.
      security:
      - apiKey: []
      parameters:
      - $ref: '#/components/parameters/Id'
      responses:
        '204':
          description: Revoked
        '401':
          $ref: '#/components/responses/Error'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'
        '503':
          $ref: '#/components/responses/Error'
    servers:
    - url: https://api.customdomain.ai/v1
      description: Hosted control-plane
    - url: http://localhost:8080/v1
      description: Local control-plane
components:
  schemas:
    AgentClient:
      type: object
      required:
      - client_id
      - client_id_issued_at
      - client_name
      - redirect_uris
      - token_endpoint_auth_method
      - grant_types
      - response_types
      properties:
        client_id:
          type: string
          description: Starts with `agc_`.
        client_id_issued_at:
          type: integer
          format: int64
          description: Unix time of the registration.
        client_name:
          type: string
        redirect_uris:
          type: array
          items:
            type: string
          description: The registered URIs, normalized.
        token_endpoint_auth_method:
          type: string
          enum:
          - none
        grant_types:
          type: array
          items:
            type: string
          examples:
          - - authorization_code
            - refresh_token
        response_types:
          type: array
          items:
            type: string
          examples:
          - - code
    AgentConsentResult:
      type: object
      required:
      - redirect_uri
      - code
      - grant_id
      properties:
        redirect_uri:
          type: string
          description: 'Where to send the person: the agent''s redirect URI with `code` and `state` added.'
        code:
          type: string
          description: The single use authorization code. It lives 5 minutes.
        state:
          type: string
        grant_id:
          type: string
    OAuthError:
      type: object
      required:
      - error
      description: The RFC 6749 and RFC 7591 error envelope the token, revoke and register endpoints answer with (the `{code, title, details}` envelope of the rest of the API is not used there).
      properties:
        error:
          type: string
          description: '`invalid_request`, `invalid_grant`, `invalid_target`, `unsupported_grant_type`, `invalid_client_metadata`, `invalid_redirect_uri`, `server_error` or `temporarily_unavailable`.'
        error_description:
          type: string
    AgentScope:
      type: string
      enum:
      - domains:read
      - domains:connect
      - domains:disconnect
      - domains:purchase
      description: 'What an agent grant may do. `domains:read` looks: availability, connections, records, certificates, diagnoses, orders and the billing standing. `domains:connect` changes: connect a domain, recheck it, reapply its records, start a one click setup. `domains:disconnect` removes a connected domain, and the call must name the domain. `domains:purchase` spends, up to the grant''s monthly cap.'
    AgentTokenResponse:
      type: object
      required:
      - access_token
      - token_type
      - expires_in
      properties:
        access_token:
          type: string
          description: An ES256 JWT. Verify it against `/.well-known/jwks.json`.
        token_type:
          type: string
          enum:
          - Bearer
        expires_in:
          type: integer
          description: Seconds the access token lives (900).
        refresh_token:
          type: string
          description: A new refresh token. The one just used no longer works.
        scope:
          type: string
          description: The scopes the grant carries, separated by spaces.
    Error:
      type: object
      required:
      - code
      - title
      properties:
        code:
          type: string
          description: stable machine code, e.g. invalid_request, unauthorized, not_found, service_unavailable, internal_error
        title:
          type: string
          description: human-readable summary
        details:
          type: string
          description: optional extra context
    AgentConsentApproval:
      type: object
      required:
      - request
      - application_id
      - scopes
      description: The body is decoded with unknown fields rejected.
      properties:
        request:
          type: string
          description: The consent request id the browser arrived with (`aqr_...`).
        member_id:
          type: string
          description: The member who approves, recorded as the grant's approver, the email recipient and the audit actor. It must belong to the workspace. With a member's own key it must be that member (`403` otherwise) and may be left out; with any other key it is required.
        application_id:
          type: string
          description: The one application of the workspace the agent will act within.
        scopes:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/AgentScope'
          description: What is approved, a subset of what the agent asked for.
        can_purchase:
          type: boolean
          deprecated: true
          description: Ignored. Purchase is allowed exactly when `domains:purchase` is among the scopes.
        spend_cap_cents:
          type: integer
          minimum: 0
          description: The monthly spend cap in US cents. Required, and above 0, with `domains:purchase`, which also needs a saved card (`409` without one).
        persist:
          type: boolean
          default: true
          description: True (the default) keeps the access until it is revoked. False ends it after `expires_days`.
        expires_days:
          type: integer
          minimum: 0
          default: 30
          description: 'With `persist: false`, days until the grant expires.'
        acknowledged_unverified:
          type: boolean
          default: false
          description: The approver confirmed they recognize the host the authorization code goes to. Required (`true`) when that host is neither a known assistant's (`verified`) nor a loopback address (`local`) in `GET /agent/consent-request/{id}`; without it such a consent is refused with `400`.
    AgentGrant:
      type: object
      required:
      - id
      - tenant_id
      - agent_client_id
      - agent_name
      - scopes
      - can_purchase
      - spend_cap_cents
      - created_at
      - spend_this_period_cents
      - period
      properties:
        id:
          type: string
          description: Starts with `grt_`.
        tenant_id:
          type: string
        agent_client_id:
          type: string
        application_id:
          type: string
          description: The application the grant is bound to.
        authorized_by:
          type: string
          description: The member who approved it.
        agent_name:
          type: string
        scopes:
          type: array
          items:
            $ref: '#/components/schemas/AgentScope'
        can_purchase:
          type: boolean
          description: True when the grant carries `domains:purchase`.
        spend_cap_cents:
          type: integer
          description: The monthly spend cap in US cents (0 without purchase access).
        expires_at:
          type: string
          format: date-time
          description: Absent for persistent access.
        created_at:
          type: string
          format: date-time
        revoked_at:
          type: string
          format: date-time
          description: Present once the access was ended.
        spend_this_period_cents:
          type: integer
          description: Spent against the cap this month.
        period:
          type: string
          description: The month `spend_this_period_cents` counts, `YYYY-MM` (UTC).
    AgentClientRegistration:
      type: object
      required:
      - client_name
      - redirect_uris
      description: RFC 7591 client metadata. Anything else a client sends (`client_uri`, `logo_uri`, `scope`, `contacts` and so on) is accepted and ignored.
      properties:
        client_name:
          type: string
          maxLength: 100
          description: Shown to the person who approves the agent. At most 100 characters, with no control or invisible characters and no Latin letters mixed with look-alike letters from another alphabet. A name that claims a well known brand is refused unless every redirect host belongs to that brand or is a loopback address.
        redirect_uris:
          type: array
          minItems: 1
          maxItems: 10
          items:
            type: string
            format: uri
            maxLength: 2000
          description: Where the authorization code may be sent. `https`, or `http` on a loopback host (`localhost`, `127.0.0.1`, `::1`) for a program on the person's own computer. No fragment and no user information. A redirect URI is matched exactly later, except for the port of a loopback one.
        grant_types:
          type: array
          items:
            type: string
          description: Optional. When sent it must include `authorization_code`; other values are ignored. The client is registered for `authorization_code` and `refresh_token`.
        response_types:
          type: array
          items:
            type: string
          description: Optional. When sent it must include `code`.
        token_endpoint_auth_method:
          type: string
          description: Ignored. Every agent client is a public client (`none`) and PKCE protects its code.
    AgentGrantList:
      type: object
      required:
      - grants
      properties:
        grants:
          type: array
          items:
            $ref: '#/components/schemas/AgentGrant'
    AgentTokenRequest:
      type: object
      required:
      - grant_type
      - client_id
      properties:
        grant_type:
          type: string
          enum:
          - authorization_code
          - refresh_token
        client_id:
          type: string
        code:
          type: string
          description: 'With `authorization_code`: the single use code from the redirect. It lives 5 minutes. Presenting a code that already issued tokens is `invalid_grant` and revokes the grant they came from (RFC 6749 §4.1.2).'
        code_verifier:
          type: string
          description: 'With `authorization_code`: the PKCE verifier for the `code_challenge` sent to authorize.'
        redirect_uri:
          type: string
          format: uri
          description: 'With `authorization_code`: exactly the `redirect_uri` sent to authorize.'
        refresh_token:
          type: string
          description: 'With `refresh_token`: the latest refresh token. It is good for one exchange.'
        resource:
          description: RFC 8707. The resource the token is for. With `authorization_code` it must be the one the person approved; with `refresh_token` it picks the audience of the new access token (the MCP endpoint when omitted). In a form body repeat the field; in JSON send a string or a list.
          oneOf:
          - type: string
            format: uri
          - type: array
            items:
              type: string
              format: uri
    AgentConsentRequest:
      type: object
      required:
      - client_id
      - client_name
      - redirect_uri
      - scopes
      - redirect_host
      - verified
      - local
      - registration
      properties:
        client_id:
          type: string
        client_name:
          type: string
        redirect_uri:
          type: string
          description: Where the authorization code goes if the person approves.
        scopes:
          type: array
          items:
            $ref: '#/components/schemas/AgentScope'
          description: What the agent asked for.
        state:
          type: string
          description: The agent's own state value, echoed back to it.
        redirect_host:
          type: string
          description: The host of `redirect_uri`. The client cannot choose it freely the way it chooses its name, so show it.
        verified:
          type: boolean
          description: True when `redirect_host` is a known assistant's own callback host or a loopback address, and the name imitates no brand.
        verified_as:
          type: string
          description: The known assistant `redirect_host` belongs to.
        local:
          type: boolean
          description: True when the code goes to a program on the approver's own computer (a loopback redirect).
        imitates:
          type: string
          description: The brand the name claims without owning the redirect host. Such a request cannot be approved.
        registration:
          type: string
          enum:
          - dynamic
          - metadata_document
          description: How the client identified itself, by RFC 7591 registration or by a Client ID Metadata Document.
        registered_at:
          type: string
          format: date-time
          description: When a dynamically registered client registered.
        client_id_host:
          type: string
          description: The host that publishes a metadata document client's document.
  responses:
    Error:
      description: 'Error envelope: {code, title, details}.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  parameters:
    Id:
      name: id
      in: path
      required: true
      schema:
        type: string
  securitySchemes:
    managementKey:
      type: http
      scheme: bearer
      description: Operator management key. Gates provisioning + reads across tenants.
    provisionSecret:
      type: apiKey
      in: header
      name: X-Provision-Secret
      description: Narrow secret held by the customer console's server, for signup provisioning and its other server to server calls (also accepted as a Bearer token, except on POST /audit, where a Bearer is always a tenant credential).
    apiKey:
      type: http
      scheme: bearer
      description: Long-lived tenant API key, cd_live_… (production) or cd_test_… (staging, development), stored hashed. Keys created before the switch to cd_ start with sk_live_… / sk_test_… and are still accepted. Scoped to the owning application's tenant.
    widgetJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Short-lived widget JWT minted server-side via POST /v1/tokens. Scoped to one application (and optionally one domain).
    browserSession:
      type: http
      scheme: bearer
      description: The session token of one cloud browser sign in, returned by `POST /browser-sessions:redeem`. It binds one session, one connection and one workspace, lives at most as long as the session, and stops working the moment the session ends. It lives in the popup's memory only.
    agentToken:
      type: oauth2
      description: 'A delegated agent access token: an ES256 JWT that lives 15 minutes, sent as a bearer token. A person approves an agent in the console and the agent exchanges its authorization code (with PKCE) at the token endpoint. The token carries the workspace, the one application the grant is bound to, the grant, the approved scopes and its audience, and is verified against `/.well-known/jwks.json`. A route that accepts it lists the scope it needs; a token without the scope is refused with `403`, and a connection or order of another application answers `404`.'
      flows:
        authorizationCode:
          authorizationUrl: https://api.customdomain.ai/oauth/agent/authorize
          tokenUrl: https://api.customdomain.ai/oauth/agent/token
          refreshUrl: https://api.customdomain.ai/oauth/agent/token
          scopes:
            domains:read: Look at availability, connections, records, certificates, diagnoses, orders and the billing standing.
            domains:connect: Connect a domain, recheck it, reapply its records and start a one click setup.
            domains:disconnect: Remove a connected domain. The call must name the domain.
            domains:purchase: Buy a domain, up to the grant's monthly spend cap.
x-refined-from:
- customdomain-ai-openapi-original.json
- customdomain-ai-openapi.yml