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

# Give the pool a shared public address

> Binds an already-allocated floating IP of yours to the pool. One public
IP, answered by every replica — an anycast address — as opposed to
`template.assign_public_ip`, which gives each replica its own.

THE OPERATION NAMES THE POOL because the pool is what makes the address
work. Each member's NAT rule is matched per hypervisor, so two members on
one hypervisor both match there, one answers and the other receives
nothing, with no signal anywhere. A pool spreads its replicas across
hypervisors, and its members here are derived from the live ones — one
per hypervisor. A replica that shares a hypervisor with an existing
member is left out rather than added and silently starved, so the address
can have fewer members than the pool has replicas; `members` says which.

Membership is maintained for you: a scale-out joins, a scale-in leaves,
and a replaced member is swapped. There is no per-replica attach to make.

The floating IP must be unattached, and the pool's subnet must already
route `0.0.0.0/0` to an internet gateway. Idempotent: re-attaching the
same address to the same pool returns it unchanged.




## OpenAPI

````yaml /api-reference/specs/compute.yaml post /v1/instance-pools/{pool_id}/floating-ips
openapi: 3.0.3
info:
  title: Basaltic Compute API
  version: 1.0.0
  description: |
    Virtual machine instances, and the images, flavors, SSH keypairs and
    instance pools they are built from. Covers the whole instance lifecycle:
    start, stop, reboot, resize and reinstall.
  contact:
    name: Basaltic Support
    email: ping@basaltic.sh
  license:
    name: Proprietary
    url: https://basaltic.sh/terms
servers:
  - url: https://compute.{region}.basaltic.sh
    description: Regional API endpoint
    variables:
      region:
        default: sa-saopaulo-1
        description: Region code
security:
  - SignatureAuth: []
paths:
  /v1/instance-pools/{pool_id}/floating-ips:
    parameters:
      - name: pool_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
    post:
      tags:
        - Compute
      summary: Give the pool a shared public address
      description: >
        Binds an already-allocated floating IP of yours to the pool. One public

        IP, answered by every replica — an anycast address — as opposed to

        `template.assign_public_ip`, which gives each replica its own.


        THE OPERATION NAMES THE POOL because the pool is what makes the address

        work. Each member's NAT rule is matched per hypervisor, so two members
        on

        one hypervisor both match there, one answers and the other receives

        nothing, with no signal anywhere. A pool spreads its replicas across

        hypervisors, and its members here are derived from the live ones — one

        per hypervisor. A replica that shares a hypervisor with an existing

        member is left out rather than added and silently starved, so the
        address

        can have fewer members than the pool has replicas; `members` says which.


        Membership is maintained for you: a scale-out joins, a scale-in leaves,

        and a replaced member is swapped. There is no per-replica attach to
        make.


        The floating IP must be unattached, and the pool's subnet must already

        route `0.0.0.0/0` to an internet gateway. Idempotent: re-attaching the

        same address to the same pool returns it unchanged.
      operationId: attachInstancePoolFloatingIp
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InstancePoolFloatingIpAttachRequest'
      responses:
        '200':
          description: Attached; the address is returned with the members it now has.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InstancePoolFloatingIpResponse'
        '400':
          description: >-
            The floating IP id is missing or malformed, the pool's subnet has no
            default route to an internet gateway, or the region has anycast
            floating IPs switched off.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: >-
            The floating IP is already attached to something, already belongs to
            another instance pool, or the pool is being deleted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - SignatureAuth: []
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      description: >-
        Optional client-generated key that makes a create replay-safe. Retrying
        a request with the same key returns the original outcome verbatim
        instead of creating a duplicate resource. Reusing a key with a different
        request body is rejected (422); a request whose key is still being
        processed returns 409. Records are honored for 24 hours. Use a UUID or
        similarly unique token.
      required: false
      schema:
        type: string
        maxLength: 255
      example: 550e8400-e29b-41d4-a716-446655440000
  schemas:
    InstancePoolFloatingIpAttachRequest:
      type: object
      required:
        - floating_ip_id
      properties:
        floating_ip_id:
          type: string
          format: uuid
          description: >-
            An already-allocated floating IP of yours, currently attached to
            nothing. This binds it to the pool; it does not allocate one.
          example: 3f9a1c7e-5b2d-4e8a-9c1f-6d3b7a2e5c9f
    InstancePoolFloatingIpResponse:
      type: object
      properties:
        floating_ip:
          $ref: '#/components/schemas/FloatingIp'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              description: Error code identifying the type of error
              example: INVALID_INPUT
            message:
              type: string
              description: Human-readable error message
              example: Invalid request parameters
            request_id:
              type: string
              format: uuid
              description: Request ID for debugging
              example: 550e8400-e29b-41d4-a716-446655440000
    FloatingIp:
      type: object
      required:
        - id
        - crn
        - ip_address
        - members
        - tags
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        crn:
          type: string
          readOnly: true
          example: crn:network:sa-saopaulo-1:my-account:floating-ip/<uuid>
        description:
          type: string
          example: Public IP for the web load balancer
        ip_address:
          type: string
          example: 10.60.128.7
        attached_to_interface_id:
          type: string
          format: uuid
          nullable: true
          description: >
            Legacy single-binding field: the sole interface this floating IP is

            bound to, or null when unattached OR when it has more than one
            member

            (an anycast floating IP). `members` is authoritative.
          example: 7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d
        instance_pool_id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
          description: >
            The instance pool this address belongs to, or null for an ordinary

            floating IP.


            A pool's address is the only one that can have more than one member.

            Its members are the pool's live replicas — one per hypervisor,

            maintained by the pool as it scales — so `attach` and `detach` on
            this

            floating IP are refused: use

            `POST /v1/instance-pools/{pool_id}/floating-ips` and

            `DELETE /v1/instance-pools/{pool_id}/floating-ips/{floating_ip_id}`.
          example: 0b2a4c6e-8d1f-4a3b-9c5e-7f2d1a4b6c8e
        members:
          type: array
          description: >
            The floating IP's bindings. A floating IP fronts 0 members
            (allocated,

            unattached), 1 member (the everyday case), or N members — an anycast

            floating IP, where one public IP is delivered to N VM NICs across

            hosts (each advertised as a /32 from the host holding it).


            MORE THAN ONE MEMBER IS ONLY POSSIBLE FOR AN INSTANCE POOL'S
            ADDRESS.

            Each member's NAT rule is matched per hypervisor, so two members on
            the

            SAME hypervisor both match there, one of them answers and the other

            receives nothing — with no signal anywhere that half the capacity is

            dark. A pool is what spreads its replicas across hypervisors, so a

            shared address is attached to a pool and its members are derived
            from

            the pool's live replicas: a scale-out joins, a scale-in leaves, and
            a

            replica sharing a hypervisor with an existing member is left out of
            the

            set rather than added to it and silently starved (so a pool can have

            more replicas than the address has members).


            With more than one member the region's edge router picks ONE member

            per connection, by hashing the flow's addresses and ports, and every

            packet of that connection goes to the same one. The members are

            separate instances that share nothing, so this spreads connections
            and

            survives the loss of a host — it is not a load balancer: there is no

            health checking of what runs inside the instance, and connections in

            progress to a member that goes away are not moved, they end.
          items:
            $ref: '#/components/schemas/FloatingIpMember'
        tags:
          type: object
          additionalProperties:
            type: string
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
    FloatingIpMember:
      type: object
      description: One binding of a floating IP.
      required:
        - health
        - created_at
      properties:
        interface_id:
          type: string
          format: uuid
          nullable: true
          description: The bound interface (instance_nic floating IPs).
        resource_id:
          type: string
          format: uuid
          nullable: true
          description: The bound resource id (lb / email_sender floating IPs).
        health:
          type: string
          description: >
            Control-plane-reflected liveness of this member. Instance-NIC
            members

            always read `unknown`: what decides whether this member is
            advertised

            is where its NIC is bound in the network fabric, which is not a

            property the control plane stores on the member row.
          example: unknown
        created_at:
          type: string
          format: date-time
          readOnly: true
  responses:
    Unauthorized:
      description: Authentication required or token invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: UNAUTHORIZED
              message: Authentication required
              request_id: 550e8400-e29b-41d4-a716-446655440000
    Forbidden:
      description: Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: ACCESS_DENIED
              message: You don't have permission to perform this action
              request_id: 550e8400-e29b-41d4-a716-446655440000
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: NOT_FOUND
              message: Resource not found
              request_id: 550e8400-e29b-41d4-a716-446655440000
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INTERNAL_ERROR
              message: An internal error occurred
              request_id: 550e8400-e29b-41d4-a716-446655440000
  securitySchemes:
    SignatureAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >
        Request signing with an access key issued to a service account. An

        HMAC-SHA256 over a canonical form of the request, close to AWS SigV4.

        The `basaltic` CLI signs for you.


        Send `Authorization`, `X-Date` (UTC, `YYYYMMDDTHHMMSSZ`) and `X-Nonce`

        (random per request); add `X-Content-Sha256` to bind a body, and

        `X-Amz-Security-Token` when using temporary credentials.


        ```

        Authorization: BASALTIC-HMAC-SHA256
        Credential=<access_key_id>/<date>/<region>/basaltic/basaltic_request,
        SignedHeaders=host;x-date;x-nonce, Signature=<hex>

        ```


        `<region>` is the region code you are calling, or `global` for the
        global

        services. A signature is valid for 5 minutes from `X-Date`, and mutating

        requests are replay-guarded on the nonce.


        **Full signing procedure, including a working implementation:**

        https://docs.basaltic.sh/authentication


        ## Rate limits

        There is no global request budget. A limit applies only where an

        operation documents a `429`, and that operation says what it counts.

        Those responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining`,

        `X-RateLimit-Reset` and, on a `429`, `Retry-After` — read them rather

        than hard-coding a number. Retrying before `Retry-After` is refused and

        extends the window. Everything else is bounded by quota, not by request

        rate.

````