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

# Check whether an agent should rotate its IP

> Requires the database-controlled organization entitlement and the `agents:ip_rotation` secret-key scope. Each submitted IP consumes one secret-key rate-limit unit, so a 10-item batch costs 10 units. The response reports that cost in `X-RateLimit-Cost`.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/agents/ip-rotation
openapi: 3.1.0
info:
  title: Foil API
  version: '2026-03-25'
  description: >-
    Customer-facing Foil server APIs for sessions, visitor fingerprints,
    organizations, and API keys.
servers:
  - url: https://api.usefoil.com
    description: Production
security: []
tags:
  - name: Sessions
    description: Session readback endpoints.
  - name: Visitor fingerprints
    description: Visitor fingerprint readback endpoints.
  - name: Organizations
    description: Organization lifecycle endpoints.
  - name: API Keys
    description: Organization API key lifecycle endpoints.
  - name: Gate
    description: >-
      Registry, organization-owned services, signup sessions, agent tokens, and
      dashboard login sessions.
  - name: Gate Webhooks
    description: Outbound Gate webhook delivery contracts.
  - name: Webhooks
    description: Manage webhook endpoints, subscriptions, and outgoing event delivery.
  - name: Events
    description: Inspect organization events and their webhook delivery attempts.
paths:
  /v1/agents/ip-rotation:
    post:
      tags:
        - Agents
      summary: Check whether an agent should rotate its IP
      description: >-
        Requires the database-controlled organization entitlement and the
        `agents:ip_rotation` secret-key scope. Each submitted IP consumes one
        secret-key rate-limit unit, so a 10-item batch costs 10 units. The
        response reports that cost in `X-RateLimit-Cost`.
      operationId: checkAgentIpRotation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentIpRotationRequest'
      responses:
        '200':
          description: Ordered agent IP rotation decisions.
          headers:
            X-RateLimit-Cost:
              description: >-
                Rate-limit units charged for this request; equal to the number
                of submitted IPs.
              schema:
                type: integer
                minimum: 1
                maximum: 10
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentIpRotationResponse'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
        '403':
          description: A secret key with the agents:ip_rotation scope is required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
        '404':
          description: The endpoint is not enabled for this organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
        '422':
          description: >-
            Invalid batch size, IP address, proxy provider tag, or desired
            country code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
        '429':
          description: >-
            Rate limit exceeded. Each submitted IP consumes one unit; honor
            Retry-After before retrying.
          headers:
            X-RateLimit-Cost:
              description: >-
                Rate-limit units attempted by this request; equal to the number
                of submitted IPs.
              schema:
                type: integer
                minimum: 1
                maximum: 10
            Retry-After:
              description: Seconds until the next acceptable retry.
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
        '503':
          description: IP intelligence is temporarily unavailable or incomplete.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
      security:
        - BearerAuth: []
components:
  schemas:
    AgentIpRotationRequest:
      type: object
      additionalProperties: false
      required:
        - items
      properties:
        items:
          type: array
          minItems: 1
          maxItems: 10
          items:
            $ref: '#/components/schemas/AgentIpRotationItem'
    AgentIpRotationResponse:
      type: object
      additionalProperties: false
      required:
        - items
      properties:
        items:
          type: array
          minItems: 1
          maxItems: 10
          items:
            $ref: '#/components/schemas/AgentIpRotationResult'
    ApiErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/PublicError'
          example:
            code: request.validation_failed
            message: Observation payload failed validation.
            status: 1
            retryable: true
            request_id: req_cf147349a4134208aebb8c70e25fb7e1
            docs_url: https://app.acme.co/signup
            details:
              fields:
                - name: Acme Growth Workspace
                  issue: required
                  expected: string
                  received: any_of
              allowed_values:
                - verified
              header_name: x-forwarded-for
              parameter_set: browser_fingerprint
              next_action: retry
      example:
        error:
          code: request.validation_failed
          message: Observation payload failed validation.
          status: 1
          retryable: true
          request_id: req_cf147349a4134208aebb8c70e25fb7e1
          docs_url: https://app.acme.co/signup
          details:
            fields:
              - name: Acme Growth Workspace
                issue: required
                expected: string
                received: any_of
            allowed_values:
              - verified
            header_name: x-forwarded-for
            parameter_set: browser_fingerprint
            next_action: retry
    AgentIpRotationItem:
      type: object
      additionalProperties: false
      required:
        - ip
        - proxy_provider
        - desired_country_code
      properties:
        ip:
          type: string
          description: >-
            Globally routable IPv4 or IPv6 address currently assigned to the
            agent.
          example: 8.8.8.8
        proxy_provider:
          type: string
          pattern: ^[A-Z0-9]+(?:_[A-Z0-9]+)*$
          maxLength: 128
          description: >-
            Uppercase snake-case provider tag from Foil's operator catalog. Foil
            matches the tag exactly and accepts catalogued aliases such as
            `BYTEFUL_DATA`, but never infers a suffix from a shared stem. The
            Agent IP rotation page lists the accepted tags. Foil records the tag
            with the sighting; it does not influence `should_cycle`.
          example: BYTEFUL
        desired_country_code:
          $ref: '#/components/schemas/IsoCountryCode'
    AgentIpRotationResult:
      type: object
      additionalProperties: false
      required:
        - ip
        - proxy_provider
        - proxy_provider_brand
        - desired_country_code
        - observed_country_code
        - country_matches
        - should_cycle
      properties:
        ip:
          type: string
          example: 8.8.8.8
        proxy_provider:
          type: string
          description: The submitted provider tag.
          example: BYTEFUL
        proxy_provider_brand:
          type: string
          pattern: ^[A-Z0-9]+(?:_[A-Z0-9]+)*$
          description: >-
            Canonical catalog brand key the submitted tag resolved to. Use this
            key in future requests.
          example: BYTEFUL
        desired_country_code:
          $ref: '#/components/schemas/IsoCountryCode'
        observed_country_code:
          anyOf:
            - $ref: '#/components/schemas/IsoCountryCode'
            - type: 'null'
          description: >-
            Country code observed by Foil IP intelligence, or null when it
            cannot be confirmed.
        country_matches:
          type: boolean
          description: Whether the observed country matches the desired country.
          example: true
        should_cycle:
          type: boolean
          description: >-
            Whether the caller should discard this IP and request another one.
            Known anonymizers, proxies, relays, residential proxies, VPNs, Tor
            exits, botnet exits, hosting networks, suspicious networks, and a
            confirmed country different from the desired one require cycling. An
            unconfirmed country does not.
          example: true
    PublicError:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - status
        - retryable
        - request_id
      properties:
        code:
          type: string
          x-foil-known-values-ref: '#/components/schemas/KnownPublicErrorCode'
          example: request.validation_failed
        message:
          type: string
          example: Observation payload failed validation.
        status:
          type: integer
          example: 1
        retryable:
          type: boolean
          example: true
        request_id:
          $ref: '#/components/schemas/RequestId'
          example: req_cf147349a4134208aebb8c70e25fb7e1
        docs_url:
          type: string
          format: uri
          example: https://app.acme.co/signup
        details:
          $ref: '#/components/schemas/ApiErrorDetails'
          example:
            fields:
              - name: Acme Growth Workspace
                issue: required
                expected: string
                received: any_of
            allowed_values:
              - verified
            header_name: x-forwarded-for
            parameter_set: browser_fingerprint
            next_action: retry
      example:
        code: request.validation_failed
        message: Observation payload failed validation.
        status: 1
        retryable: true
        request_id: req_cf147349a4134208aebb8c70e25fb7e1
        docs_url: https://app.acme.co/signup
        details:
          fields:
            - name: Acme Growth Workspace
              issue: required
              expected: string
              received: any_of
          allowed_values:
            - verified
          header_name: x-forwarded-for
          parameter_set: browser_fingerprint
          next_action: retry
    IsoCountryCode:
      type: string
      description: Uppercase ISO 3166-1 alpha-2 country code.
      enum:
        - AD
        - AE
        - AF
        - AG
        - AI
        - AL
        - AM
        - AO
        - AQ
        - AR
        - AS
        - AT
        - AU
        - AW
        - AX
        - AZ
        - BA
        - BB
        - BD
        - BE
        - BF
        - BG
        - BH
        - BI
        - BJ
        - BL
        - BM
        - BN
        - BO
        - BQ
        - BR
        - BS
        - BT
        - BV
        - BW
        - BY
        - BZ
        - CA
        - CC
        - CD
        - CF
        - CG
        - CH
        - CI
        - CK
        - CL
        - CM
        - CN
        - CO
        - CR
        - CU
        - CV
        - CW
        - CX
        - CY
        - CZ
        - DE
        - DJ
        - DK
        - DM
        - DO
        - DZ
        - EC
        - EE
        - EG
        - EH
        - ER
        - ES
        - ET
        - FI
        - FJ
        - FK
        - FM
        - FO
        - FR
        - GA
        - GB
        - GD
        - GE
        - GF
        - GG
        - GH
        - GI
        - GL
        - GM
        - GN
        - GP
        - GQ
        - GR
        - GS
        - GT
        - GU
        - GW
        - GY
        - HK
        - HM
        - HN
        - HR
        - HT
        - HU
        - ID
        - IE
        - IL
        - IM
        - IN
        - IO
        - IQ
        - IR
        - IS
        - IT
        - JE
        - JM
        - JO
        - JP
        - KE
        - KG
        - KH
        - KI
        - KM
        - KN
        - KP
        - KR
        - KW
        - KY
        - KZ
        - LA
        - LB
        - LC
        - LI
        - LK
        - LR
        - LS
        - LT
        - LU
        - LV
        - LY
        - MA
        - MC
        - MD
        - ME
        - MF
        - MG
        - MH
        - MK
        - ML
        - MM
        - MN
        - MO
        - MP
        - MQ
        - MR
        - MS
        - MT
        - MU
        - MV
        - MW
        - MX
        - MY
        - MZ
        - NA
        - NC
        - NE
        - NF
        - NG
        - NI
        - NL
        - 'NO'
        - NP
        - NR
        - NU
        - NZ
        - OM
        - PA
        - PE
        - PF
        - PG
        - PH
        - PK
        - PL
        - PM
        - PN
        - PR
        - PS
        - PT
        - PW
        - PY
        - QA
        - RE
        - RO
        - RS
        - RU
        - RW
        - SA
        - SB
        - SC
        - SD
        - SE
        - SG
        - SH
        - SI
        - SJ
        - SK
        - SL
        - SM
        - SN
        - SO
        - SR
        - SS
        - ST
        - SV
        - SX
        - SY
        - SZ
        - TC
        - TD
        - TF
        - TG
        - TH
        - TJ
        - TK
        - TL
        - TM
        - TN
        - TO
        - TR
        - TT
        - TV
        - TW
        - TZ
        - UA
        - UG
        - UM
        - US
        - UY
        - UZ
        - VA
        - VC
        - VE
        - VG
        - VI
        - VN
        - VU
        - WF
        - WS
        - YE
        - YT
        - ZA
        - ZM
        - ZW
      example: US
    RequestId:
      type: string
      pattern: ^req_[0-9a-f]{32}$
      example: req_cf147349a4134208aebb8c70e25fb7e1
    ApiErrorDetails:
      type: object
      properties:
        fields:
          type: array
          items:
            $ref: '#/components/schemas/ApiFieldIssue'
            example:
              name: Acme Growth Workspace
              issue: required
              expected: string
              received: any_of
          example:
            - name: Acme Growth Workspace
              issue: required
              expected: string
              received: any_of
        allowed_values:
          type: array
          items:
            type: string
            example: verified
          example:
            - verified
        header_name:
          type: string
          example: x-forwarded-for
        parameter_set:
          type: string
          example: browser_fingerprint
        next_action:
          type: string
          enum:
            - retry
            - new_session
            - reload_bundle
            - contact_support
          example: retry
      additionalProperties: true
      example:
        fields:
          - name: Acme Growth Workspace
            issue: required
            expected: string
            received: any_of
        allowed_values:
          - verified
        header_name: x-forwarded-for
        parameter_set: browser_fingerprint
        next_action: retry
    ApiFieldIssue:
      type: object
      additionalProperties: false
      required:
        - name
        - issue
      properties:
        name:
          type: string
          example: Acme Growth Workspace
        issue:
          type: string
          example: required
        expected:
          type: string
          example: string
        received:
          anyOf:
            - type: string
              example: '0'
            - type: number
              example: 1.5
            - type: boolean
              example: true
            - type: 'null'
              example: null
          example: any_of
      example:
        name: Acme Growth Workspace
        issue: required
        expected: string
        received: any_of
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Send Authorization: Bearer <token>. Gate business endpoints require sk_*
        secret keys. Gate workflow endpoints use gate-native bearer tokens such
        as gtpoll_* or agt_* where documented.

````