> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sailresearch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Set a Sailbox's egress policy

> Replaces the Sailbox's whole policy with a saved policy or an inline document. It works on a running, paused, or sleeping Sailbox. Connections opened after the call follow the new policy; a connection that is already open keeps the policy it was opened under until it closes. A Sailbox with exposed ports cannot be given `no_network`; remove its listeners first.



## OpenAPI

````yaml /sailbox-openapi.json put /sailboxes/{sailbox_id}/egress-policy
openapi: 3.1.0
info:
  title: Sail Sailbox API
  version: '2026-09-07'
  description: >-
    Create and operate Sailboxes over HTTP. Sailboxes are fast-booting virtual
    machines that you can pause, resume, and checkpoint.


    Run commands, stream files, manage lifecycle and networking, and inspect
    usage. Turning on SSH and building an image still require an SDK or the CLI.
    See the [HTTP API guide](/sailboxes-http-api).
servers:
  - url: https://sailbox-api.sailresearch.com/v1
security:
  - BearerAuth: []
tags:
  - name: Apps
    description: Groups that own Sailboxes. One app per workload.
  - name: Lifecycle
    description: >-
      A Sailbox's whole life: create it, watch it, stop and start it, terminate
      it.
  - name: Checkpoints
    description: Save a Sailbox to start from later, and copy a running one.
  - name: Exec
    description: Run commands and control their standard input and terminals.
  - name: Files
    description: Stream regular files into and out of a Sailbox.
  - name: Networking
    description: >-
      Publish ports, serve them on hostnames you own, and identify a Sailbox to
      other Sailboxes.
  - name: Secrets
    description: >-
      Organization values that egress policy rules can add to matching requests.
      Sail never returns a stored value.
  - name: Egress policies
    description: >-
      What a Sailbox may connect to, and what happens to the HTTPS requests it
      sends.
  - name: Volumes
    description: >-
      Shared storage that outlives any one Sailbox. Alpha: these endpoints can
      still change.
  - name: SSH access
    description: Certificates for connecting to a Sailbox with `ssh`.
  - name: Usage
    description: Resource usage and spend.
  - name: Identity
    description: Who your API key belongs to.
paths:
  /sailboxes/{sailbox_id}/egress-policy:
    put:
      tags:
        - Egress policies
      summary: Set a Sailbox's egress policy
      description: >-
        Replaces the Sailbox's whole policy with a saved policy or an inline
        document. It works on a running, paused, or sleeping Sailbox.
        Connections opened after the call follow the new policy; a connection
        that is already open keeps the policy it was opened under until it
        closes. A Sailbox with exposed ports cannot be given `no_network`;
        remove its listeners first.
      operationId: setSailboxEgressPolicy
      parameters:
        - $ref: '#/components/parameters/SailboxId'
        - $ref: '#/components/parameters/OwnerOverrideReason'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetSailboxEgressPolicyRequest'
            example:
              policy_id: ep_6f3a8d21-4b7c-4e90-a125-9d2f6c8b3a41
      responses:
        '200':
          description: The Sailbox's new policy.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SailboxEgressPolicy'
              example:
                policy_id: ep_6f3a8d21-4b7c-4e90-a125-9d2f6c8b3a41
                name: github
                document:
                  allowlist:
                    - github.com
                    - api.github.com
                  rules:
                    api.github.com:
                      - request:
                          set:
                            headers:
                              authorization: Bearer ${secrets.GITHUB_TOKEN}
        '400':
          description: >-
            The request was rejected. See the error message for the offending
            field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: policy_id or document is required
                  type: invalid_request_error
                  param: null
                  code: null
        '401':
          description: The API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: Invalid API key
                  type: authentication_error
                  param: null
                  code: invalid_api_key
        '402':
          description: >-
            The organization is out of credits. The error carries a
            `billing_url` pointing at the page where you add them. Retry once
            you have.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: >-
                    Your API key has been disabled due to insufficient credits.
                    Visit https://app.sailresearch.com/billing to add credits.
                  type: billing_error
                  param: null
                  code: credits_exhausted
                  billing_url: https://app.sailresearch.com/billing
        '403':
          description: The API key is not allowed to perform this operation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: sailboxes require an organization-scoped API key
                  type: permission_error
                  param: null
                  code: null
        '404':
          description: >-
            The Sailbox does not exist in your organization, or `policy_id`
            names no saved policy in it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: >-
                    egress policy ep_6f3a8d21-4b7c-4e90-a125-9d2f6c8b3a41 not
                    found
                  type: not_found_error
                  param: null
                  code: null
        '409':
          description: >-
            The Sailbox is terminated, or it has exposed ports and the new
            policy would cut it off from the network.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: >-
                    a Sailbox with exposed ports cannot be cut off from the
                    network; remove its listeners first
                  type: conflict_error
                  param: null
                  code: null
        '413':
          description: >-
            The encoded request body is larger than 72 KiB. A document over its
            own 64 KiB limit inside a smaller body is rejected with `400`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: request body too large
                  type: invalid_request_error
                  param: null
                  code: null
        '429':
          description: >-
            For its first ten minutes a new organization is capped on how many
            requests it can have in flight at once, and yours is over that cap.
            The request never started, so retry it unchanged after the delay in
            the `Retry-After` header. The limit clears as those requests finish.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: >-
                    Too many concurrent requests. Please retry after some of
                    your organization's in-flight requests complete.
                  type: rate_limit_error
                  param: null
                  code: rate_limited
          headers:
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
        '500':
          description: Server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: >-
                    the egress policy was saved but not yet applied to the
                    network path; retry to apply it
                  type: server_error
                  param: null
                  code: null
        '503':
          description: >-
            Sail is momentarily unavailable. Retry after the delay in the
            `Retry-After` header when one is present, and with backoff
            otherwise.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  message: Authentication service unavailable
                  type: server_error
                  param: null
                  code: null
          headers:
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
components:
  parameters:
    SailboxId:
      name: sailbox_id
      in: path
      required: true
      schema:
        type: string
      description: >-
        Id of the Sailbox, as returned by create. It is `sb_` followed by a
        UUID.
    OwnerOverrideReason:
      name: X-Sail-Owner-Override-Reason
      in: header
      required: false
      schema:
        type: string
        pattern: ^[ -~]*$
      description: >-
        Lets an organization admin operate a `private` Sailbox someone else
        created. Say why in plain text; the reason goes into your organization's
        audit log, and the operation is refused without it. Ignored on Sailboxes
        you could already operate.


        Pause, resume, sleep, scheduled wake, upgrade, and terminate accept an
        override. Setting an egress policy accepts one too. Running commands and
        moving files accept one through an SDK or the CLI. Publishing and
        unpublishing ports, adding and removing custom domains, checkpointing,
        and creating from a checkpoint stay with the creator.
  schemas:
    SetSailboxEgressPolicyRequest:
      type: object
      additionalProperties: false
      oneOf:
        - required:
            - policy_id
        - required:
            - document
      properties:
        policy_id:
          type: string
          pattern: >-
            ^(?:ep|hp)_[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
          description: >-
            ID of a saved policy, as returned by create. Send this or
            `document`, not both.
        document:
          $ref: '#/components/schemas/EgressPolicyDocument'
          description: >-
            A policy document written inline. It cannot use secrets; save it as
            a policy first.
    SailboxEgressPolicy:
      type: object
      additionalProperties: false
      properties:
        policy_id:
          oneOf:
            - type: string
              pattern: >-
                ^(?:ep|hp)_[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
            - type: 'null'
          description: >-
            ID of the saved policy the Sailbox uses, or `null` when its policy
            was written inline or it was created without one.
        name:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Display name of the saved policy, or `null` when `policy_id` is
            `null`.
        document:
          $ref: '#/components/schemas/EgressPolicyDocument'
          description: >-
            The policy document the Sailbox runs under. `{}` when every host is
            reachable and no rules apply.
      required:
        - policy_id
        - name
        - document
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorObject'
    EgressPolicyDocument:
      type: object
      additionalProperties: false
      properties:
        no_network:
          type: boolean
          description: >-
            Remove all network access, inbound included; no other field may be
            set beside it. Leave it out (or send `false`) otherwise.
            https://docs.sailresearch.com/sailboxes-egress-policy-reference#no-network
        allowlist:
          oneOf:
            - type: array
              items:
                type: string
              maxItems: 128
            - type: 'null'
          description: >-
            The destinations the Sailbox may connect to. Leave it out (or send
            `null`) to allow every destination; an empty list allows none.
            https://docs.sailresearch.com/sailboxes-egress-policy-reference#entries
        blocked:
          oneOf:
            - type: array
              items:
                type: string
              maxItems: 128
            - type: 'null'
          description: >-
            Destinations removed from what the Sailbox may otherwise reach.
            Leave it out, or send `null` or `[]`, to block nothing.
            https://docs.sailresearch.com/sailboxes-egress-policy-reference#blocked
        rules:
          $ref: '#/components/schemas/EgressPolicyRules'
          description: >-
            What happens to the HTTPS requests sent to each host: change the
            request, forward it, or answer it. Leave it out to apply no rules.
            https://docs.sailresearch.com/sailboxes-egress-policy-reference#rules
        missing_alpn:
          type: object
          propertyNames:
            pattern: >-
              ^[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*(?![0-9A-Za-z.\u0130\u212A-]{254})[A-Za-z0-9\u0130\u212A](?:[A-Za-z0-9\u0130\u212A-]{0,61}[A-Za-z0-9\u0130\u212A])?(?:\.[A-Za-z0-9\u0130\u212A](?:[A-Za-z0-9\u0130\u212A-]{0,61}[A-Za-z0-9\u0130\u212A])?)*[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$
          additionalProperties:
            type: string
            enum:
              - http/1.1
          description: >-
            Rarely needed: the HTTP version to assume for an exact host under
            `rules` when a client does not announce one.
            https://docs.sailresearch.com/sailboxes-egress-policy-reference#missing-alpn
      description: >-
        An egress policy: what a Sailbox may connect to (`no_network`,
        `allowlist`, and `blocked`) and what happens to the HTTPS requests it
        sends (`rules`). Every field is optional. The empty document `{}` allows
        every destination and applies no rules. Sail saves a normalized form
        (for example, host names are lowercased and defaults are filled in), so
        reading a policy back can return a different shape with the same
        behavior. At most 64 KiB when encoded. Guide:
        https://docs.sailresearch.com/sailboxes-egress-policy
    ErrorObject:
      type: object
      required:
        - message
        - type
        - param
        - code
      properties:
        message:
          type: string
          description: Human-readable description of what went wrong.
        type:
          type: string
          description: >-
            Error category: `invalid_request_error`, `authentication_error`,
            `permission_error`, `billing_error`, `not_found_error`,
            `conflict_error`, `rate_limit_error`, `quota_exceeded_error`,
            `not_implemented_error`, or `server_error`.
        param:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            The request field the error refers to, when the error is about one
            field.
        code:
          oneOf:
            - type: string
            - type: integer
            - type: 'null'
          description: >-
            Stable short code for the error, when one applies. Errors relayed
            from the Sailbox runtime carry its status token, for example
            `already_exists` or `failed_precondition` on a 409, which the HTTP
            status alone does not distinguish.
        billing_url:
          type: string
          format: uri
          description: Page where you add credits. Sent with a 402.
      additionalProperties: true
    EgressPolicyRules:
      type: object
      maxProperties: 100
      propertyNames:
        pattern: >-
          ^[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*(?:\*(?:\.(?![0-9A-Za-z.\u0130\u212A-]{254})[A-Za-z0-9\u0130\u212A](?:[A-Za-z0-9\u0130\u212A-]{0,61}[A-Za-z0-9\u0130\u212A])?(?:\.[A-Za-z0-9\u0130\u212A](?:[A-Za-z0-9\u0130\u212A-]{0,61}[A-Za-z0-9\u0130\u212A])?)*)?|(?![0-9A-Za-z.\u0130\u212A-]{254})[A-Za-z0-9\u0130\u212A](?:[A-Za-z0-9\u0130\u212A-]{0,61}[A-Za-z0-9\u0130\u212A])?(?:\.[A-Za-z0-9\u0130\u212A](?:[A-Za-z0-9\u0130\u212A-]{0,61}[A-Za-z0-9\u0130\u212A])?)*)[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$
      additionalProperties:
        type: array
        minItems: 1
        maxItems: 100
        items:
          $ref: '#/components/schemas/EgressPolicyRule'
        description: Rules for this host, in the order Sail tests them.
      description: >-
        Host patterns mapped to the rules for HTTPS requests to them. Use an
        exact hostname, `*.example.com` for one direct subdomain, or `*` for any
        host without a more specific entry. A hostname is at most 253
        characters. A document can hold at most 100 host patterns and 100 rules
        in total.
    EgressPolicyRule:
      type: object
      additionalProperties: false
      description: >-
        One rule. Rules run in order and the first match decides the result.
        Only the last rule may omit `match`. Use `respond` by itself, or combine
        `forward` and `request` as needed.
      properties:
        match:
          $ref: '#/components/schemas/EgressPolicyRequestMatch'
        respond:
          $ref: '#/components/schemas/EgressPolicyResponse'
        forward:
          $ref: '#/components/schemas/EgressPolicyForward'
        request:
          $ref: '#/components/schemas/EgressPolicyRequestChange'
      not:
        anyOf:
          - required:
              - respond
              - forward
          - required:
              - respond
              - request
    EgressPolicyRequestMatch:
      type: object
      additionalProperties: false
      description: >-
        Conditions tested against the request before any changes are made. At
        least one condition is required.
      anyOf:
        - required:
            - method
        - required:
            - path
        - required:
            - headers
          properties:
            headers:
              minItems: 1
        - required:
            - query
          properties:
            query:
              minItems: 1
      properties:
        method:
          description: >-
            One or more case-sensitive HTTP methods, such as `GET`, as a single
            string or a nonempty list of strings.
          oneOf:
            - type: string
              maxLength: 4096
              pattern: ^[0-9A-Za-z!#$%&'*+\-.^_`|~]+$
            - type: array
              minItems: 1
              items:
                type: string
                maxLength: 4096
                pattern: ^[0-9A-Za-z!#$%&'*+\-.^_`|~]+$
        path:
          $ref: '#/components/schemas/EgressPolicyPathMatcher'
          description: Matches an absolute request path. Each value must start with `/`.
        headers:
          type: array
          maxItems: 100
          items:
            $ref: '#/components/schemas/EgressPolicyHeaderNameValueMatcher'
          description: Header conditions. Every entry must match.
        query:
          type: array
          maxItems: 100
          items:
            $ref: '#/components/schemas/EgressPolicyQueryNameValueMatcher'
          description: Query parameter conditions. Every entry must match.
    EgressPolicyResponse:
      type: object
      additionalProperties: false
      required:
        - status
      description: >-
        A response Sail returns in place of the destination. The request is not
        sent on.
      properties:
        status:
          type: integer
          minimum: 200
          maximum: 599
          description: HTTP status code to return.
        headers:
          type: object
          propertyNames:
            pattern: >-
              ^(?![\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*(?:[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii\u0130][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Hh][Oo][Ss][Tt]|[Kk\u212A][Ee][Ee][Pp]-[Aa][Ll][Ii\u0130][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy]-[Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii\u0130][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy]-[Aa][Uu][Tt][Hh][Oo][Rr][Ii\u0130][Zz][Aa][Tt][Ii\u0130][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy]-[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii\u0130][Oo][Nn]|[Tt][Ee]|[Tt][Rr][Aa][Ii\u0130][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr]-[Ee][Nn][Cc][Oo][Dd][Ii\u0130][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee])[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$)[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*[0-9A-Za-z!#$%&'*+\-.^_`|~\u0130\u212A]{1,128}[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$
          additionalProperties:
            description: >-
              One string or a nonempty list of strings. Each string is limited
              to 4096 bytes of UTF-8.
            oneOf:
              - type: string
                maxLength: 4096
                pattern: >-
                  ^(?:(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$(?!\{))*|(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$\$)*)$
              - type: array
                minItems: 1
                items:
                  type: string
                  maxLength: 4096
                  pattern: >-
                    ^(?:(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$(?!\{))*|(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$\$)*)$
          description: >-
            Headers to return. Secret references are not allowed here.
            Sail-managed headers such as `host` and `content-length` cannot be
            set, and a header name is at most 128 characters.
        body:
          type: string
          maxLength: 65536
          pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
          description: >-
            Response body, up to 64 KiB as UTF-8. Secret references are not
            allowed here.
      allOf:
        - if:
            properties:
              status:
                enum:
                  - 204
                  - 304
          then:
            not:
              required:
                - body
    EgressPolicyForward:
      type: object
      additionalProperties: false
      required:
        - host
      description: Another HTTPS host to send the request to.
      properties:
        host:
          type: string
          pattern: >-
            ^[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*(?![0-9A-Za-z.\u0130\u212A-]{254})[A-Za-z0-9\u0130\u212A](?:[A-Za-z0-9\u0130\u212A-]{0,61}[A-Za-z0-9\u0130\u212A])?(?:\.[A-Za-z0-9\u0130\u212A](?:[A-Za-z0-9\u0130\u212A-]{0,61}[A-Za-z0-9\u0130\u212A])?)*[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$
          description: >-
            Exact hostname, without a scheme, port, or wildcard. At most 253
            characters after surrounding whitespace is trimmed.
        port:
          type: integer
          minimum: 0
          maximum: 65535
          description: HTTPS port. Omit it, or send `0`, to use 443.
    EgressPolicyRequestChange:
      type: object
      additionalProperties: false
      minProperties: 1
      description: >-
        Changes to make before sending the request. A header, query parameter,
        or path can be targeted only once in a rule.
      properties:
        set:
          $ref: '#/components/schemas/EgressPolicySetChange'
        add:
          $ref: '#/components/schemas/EgressPolicyAddChange'
        remove:
          $ref: '#/components/schemas/EgressPolicyRemoveChange'
    EgressPolicyPathMatcher:
      description: >-
        A plain string means an exact match. Use `equals`, `prefix`, or `one_of`
        to choose the matching rule explicitly. Every value must start with `/`.
        Each string is limited to 4096 bytes of UTF-8. Secret references are not
        allowed in matchers.
      oneOf:
        - type: string
          maxLength: 4096
          pattern: ^/(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - equals
          properties:
            equals:
              type: string
              maxLength: 4096
              pattern: ^/(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - prefix
          properties:
            prefix:
              type: string
              maxLength: 4096
              pattern: ^/(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - one_of
          properties:
            one_of:
              type: array
              minItems: 1
              items:
                type: string
                maxLength: 4096
                pattern: ^/(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
    EgressPolicyHeaderNameValueMatcher:
      type: object
      additionalProperties: false
      minProperties: 1
      properties:
        name:
          $ref: '#/components/schemas/EgressPolicyHeaderNameMatcher'
          description: Matches the header name.
        value:
          $ref: '#/components/schemas/EgressPolicyMatcher'
          description: Matches its value.
        present:
          type: boolean
          description: >-
            Set to `false` with `name` to match when that name is absent. When
            omitted or true, each name or value condition you provide must be
            present and match.
      anyOf:
        - required:
            - name
        - required:
            - value
      allOf:
        - if:
            required:
              - present
            properties:
              present:
                const: false
          then:
            required:
              - name
            not:
              required:
                - value
    EgressPolicyQueryNameValueMatcher:
      type: object
      additionalProperties: false
      minProperties: 1
      properties:
        name:
          $ref: '#/components/schemas/EgressPolicyMatcher'
          description: Matches the query parameter name.
        value:
          $ref: '#/components/schemas/EgressPolicyMatcher'
          description: Matches its value.
        present:
          type: boolean
          description: >-
            Set to `false` with `name` to match when that name is absent. When
            omitted or true, each name or value condition you provide must be
            present and match.
      anyOf:
        - required:
            - name
        - required:
            - value
      allOf:
        - if:
            required:
              - present
            properties:
              present:
                const: false
          then:
            required:
              - name
            not:
              required:
                - value
    EgressPolicySetChange:
      type: object
      additionalProperties: false
      description: >-
        Values to replace or create. At least one of `path`, `headers`, or
        `query` must name a target.
      anyOf:
        - required:
            - path
        - required:
            - headers
          properties:
            headers:
              minProperties: 1
        - required:
            - query
          properties:
            query:
              minProperties: 1
      properties:
        path:
          type: string
          maxLength: 4096
          pattern: ^/(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
          description: Replacement absolute path. Secret references are not allowed here.
        headers:
          type: object
          propertyNames:
            pattern: >-
              ^(?![\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*(?:[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii\u0130][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Hh][Oo][Ss][Tt]|[Kk\u212A][Ee][Ee][Pp]-[Aa][Ll][Ii\u0130][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy]-[Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii\u0130][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy]-[Aa][Uu][Tt][Hh][Oo][Rr][Ii\u0130][Zz][Aa][Tt][Ii\u0130][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy]-[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii\u0130][Oo][Nn]|[Tt][Ee]|[Tt][Rr][Aa][Ii\u0130][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr]-[Ee][Nn][Cc][Oo][Dd][Ii\u0130][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee])[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$)[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*[0-9A-Za-z!#$%&'*+\-.^_`|~\u0130\u212A]{1,128}[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$
          additionalProperties:
            description: >-
              One string or a nonempty list of strings. Each string is limited
              to 4096 bytes of UTF-8.
            oneOf:
              - type: string
                maxLength: 4096
                pattern: >-
                  ^(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$\$|\$\{secrets\.[A-Za-z0-9][A-Za-z0-9_-]{0,127}\})*$
              - type: array
                minItems: 1
                items:
                  type: string
                  maxLength: 4096
                  pattern: >-
                    ^(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$\$|\$\{secrets\.[A-Za-z0-9][A-Za-z0-9_-]{0,127}\})*$
          description: >-
            Headers to set. Values may include `${secrets.NAME}` for a secret
            that already exists in your organization. Write a literal dollar
            sign as `$$`. Sail-managed headers such as `host` and
            `content-length` cannot be set, and a header name is at most 128
            characters.
        query:
          type: object
          propertyNames:
            minLength: 1
            maxLength: 4096
            pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
          additionalProperties:
            description: >-
              One string or a nonempty list of strings. Each string is limited
              to 4096 bytes of UTF-8.
            oneOf:
              - type: string
                maxLength: 4096
                pattern: >-
                  ^(?:[^$\r\n]|\$\$|\$\{secrets\.[A-Za-z0-9][A-Za-z0-9_-]{0,127}\})*$
              - type: array
                minItems: 1
                items:
                  type: string
                  maxLength: 4096
                  pattern: >-
                    ^(?:[^$\r\n]|\$\$|\$\{secrets\.[A-Za-z0-9][A-Za-z0-9_-]{0,127}\})*$
          description: >-
            Query parameters to set. Values may include `${secrets.NAME}` for a
            secret that already exists in your organization. Write a literal
            dollar sign as `$$`.
    EgressPolicyAddChange:
      type: object
      additionalProperties: false
      description: >-
        Values to append. Secret references are not allowed here. At least one
        of the two maps must be nonempty.
      anyOf:
        - required:
            - headers
          properties:
            headers:
              minProperties: 1
        - required:
            - query
          properties:
            query:
              minProperties: 1
      properties:
        headers:
          type: object
          propertyNames:
            pattern: >-
              ^(?![\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*(?:[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii\u0130][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Hh][Oo][Ss][Tt]|[Kk\u212A][Ee][Ee][Pp]-[Aa][Ll][Ii\u0130][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy]-[Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii\u0130][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy]-[Aa][Uu][Tt][Hh][Oo][Rr][Ii\u0130][Zz][Aa][Tt][Ii\u0130][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy]-[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii\u0130][Oo][Nn]|[Tt][Ee]|[Tt][Rr][Aa][Ii\u0130][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr]-[Ee][Nn][Cc][Oo][Dd][Ii\u0130][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee])[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$)[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*[0-9A-Za-z!#$%&'*+\-.^_`|~\u0130\u212A]{1,128}[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$
          additionalProperties:
            description: >-
              One string or a nonempty list of strings. Each string is limited
              to 4096 bytes of UTF-8.
            oneOf:
              - type: string
                maxLength: 4096
                pattern: >-
                  ^(?:(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$(?!\{))*|(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$\$)*)$
              - type: array
                minItems: 1
                items:
                  type: string
                  maxLength: 4096
                  pattern: >-
                    ^(?:(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$(?!\{))*|(?:[^\u0000-\u0008\u000A-\u001F\u007F$]|\$\$)*)$
          description: >-
            Headers to append. Sail-managed headers such as `host` and
            `content-length` cannot be changed, and a header name is at most 128
            characters.
        query:
          type: object
          propertyNames:
            minLength: 1
            maxLength: 4096
            pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
          additionalProperties:
            description: >-
              One string or a nonempty list of strings. Each string is limited
              to 4096 bytes of UTF-8.
            oneOf:
              - type: string
                maxLength: 4096
                pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
              - type: array
                minItems: 1
                items:
                  type: string
                  maxLength: 4096
                  pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
          description: Query parameters to append.
    EgressPolicyRemoveChange:
      type: object
      additionalProperties: false
      description: >-
        Header and query parameter names to remove. At least one of the two
        lists must be nonempty.
      anyOf:
        - required:
            - headers
          properties:
            headers:
              minItems: 1
        - required:
            - query
          properties:
            query:
              minItems: 1
      properties:
        headers:
          type: array
          uniqueItems: true
          items:
            type: string
            pattern: >-
              ^(?![\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*(?:[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii\u0130][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Hh][Oo][Ss][Tt]|[Kk\u212A][Ee][Ee][Pp]-[Aa][Ll][Ii\u0130][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy]-[Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii\u0130][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy]-[Aa][Uu][Tt][Hh][Oo][Rr][Ii\u0130][Zz][Aa][Tt][Ii\u0130][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy]-[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii\u0130][Oo][Nn]|[Tt][Ee]|[Tt][Rr][Aa][Ii\u0130][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr]-[Ee][Nn][Cc][Oo][Dd][Ii\u0130][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee])[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$)[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*[0-9A-Za-z!#$%&'*+\-.^_`|~\u0130\u212A]{1,128}[\t-\r\u0020\u0085\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]*$
          description: >-
            Header names to remove. Sail-managed headers such as `host` and
            `content-length` cannot be changed, and a header name is at most 128
            characters.
        query:
          type: array
          uniqueItems: true
          items:
            type: string
            minLength: 1
            maxLength: 4096
            pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
          description: Query parameter names to remove.
    EgressPolicyHeaderNameMatcher:
      description: >-
        A plain string means an exact match. Use `equals`, `prefix`, or `one_of`
        to choose the matching rule explicitly. Each string is limited to 4096
        bytes of UTF-8. Secret references are not allowed in matchers. The
        Sail-managed names `content-length`, `host`, `trailer`, and
        `transfer-encoding` are rejected in every matching form.
      oneOf:
        - type: string
          maxLength: 4096
          pattern: >-
            ^(?!(?:[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Hh][Oo][Ss][Tt]|[Tt][Rr][Aa][Ii\u0130][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr]-[Ee][Nn][Cc][Oo][Dd][Ii\u0130][Nn][Gg])$)(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - equals
          properties:
            equals:
              type: string
              maxLength: 4096
              pattern: >-
                ^(?!(?:[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Hh][Oo][Ss][Tt]|[Tt][Rr][Aa][Ii\u0130][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr]-[Ee][Nn][Cc][Oo][Dd][Ii\u0130][Nn][Gg])$)(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - prefix
          properties:
            prefix:
              type: string
              maxLength: 4096
              pattern: >-
                ^(?!(?:[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Hh][Oo][Ss][Tt]|[Tt][Rr][Aa][Ii\u0130][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr]-[Ee][Nn][Cc][Oo][Dd][Ii\u0130][Nn][Gg])$)(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - one_of
          properties:
            one_of:
              type: array
              minItems: 1
              items:
                type: string
                maxLength: 4096
                pattern: >-
                  ^(?!(?:[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Hh][Oo][Ss][Tt]|[Tt][Rr][Aa][Ii\u0130][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr]-[Ee][Nn][Cc][Oo][Dd][Ii\u0130][Nn][Gg])$)(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
    EgressPolicyMatcher:
      description: >-
        A plain string means an exact match. Use `equals`, `prefix`, or `one_of`
        to choose the matching rule explicitly. Each string is limited to 4096
        bytes of UTF-8. Secret references are not allowed in matchers.
      oneOf:
        - type: string
          maxLength: 4096
          pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - equals
          properties:
            equals:
              type: string
              maxLength: 4096
              pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - prefix
          properties:
            prefix:
              type: string
              maxLength: 4096
              pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
        - type: object
          additionalProperties: false
          required:
            - one_of
          properties:
            one_of:
              type: array
              minItems: 1
              items:
                type: string
                maxLength: 4096
                pattern: ^(?:(?:[^$]|\$(?!\{))*|(?:[^$\r\n]|\$\$)*)$
  headers:
    RetryAfter:
      description: >-
        How many seconds to wait before retrying. On a 429 it also means the
        request never started, so the retry can reuse the same
        `Idempotency-Key`.
      schema:
        type: integer
        minimum: 0
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key

````