> ## 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.

# Get the record-import outcome

> What came of `import_existing_records` — reading the domain's records off
the provider it was moving away from.

Its own resource rather than a field on the zone, because it describes one
event that happened once when the zone was created and never changes.

Poll this after creating a zone with `import_existing_records: true`:
`state` is `pending` while the background job runs. **Read `complete`
before you switch your old provider off** — see the schema.




## OpenAPI

````yaml /api-reference/specs/dns.yaml get /v1/zones/{zone_id}/record-import
openapi: 3.0.3
info:
  title: Basaltic DNS API
  version: 1.0.0
  description: |
    Authoritative hosted zones and their records, signed with DNSSEC. A zone
    is only served once its ownership is verified; associating a zone with a
    VPC makes it resolvable privately inside that network.
  contact:
    name: Basaltic Support
    email: ping@basaltic.sh
  license:
    name: Proprietary
    url: https://basaltic.sh/terms
servers:
  - url: https://dns.basaltic.sh
    description: Global API endpoint
security:
  - SignatureAuth: []
paths:
  /v1/zones/{zone_id}/record-import:
    get:
      tags:
        - DNS
      summary: Get the record-import outcome
      description: >
        What came of `import_existing_records` — reading the domain's records
        off

        the provider it was moving away from.


        Its own resource rather than a field on the zone, because it describes
        one

        event that happened once when the zone was created and never changes.


        Poll this after creating a zone with `import_existing_records: true`:

        `state` is `pending` while the background job runs. **Read `complete`

        before you switch your old provider off** — see the schema.
      operationId: getZoneRecordImport
      parameters:
        - $ref: '#/components/parameters/ZoneId'
      responses:
        '200':
          description: The import outcome
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ZoneRecordImportResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: |
            No import was requested for this zone — the ordinary case for a zone
            created without `import_existing_records`. Also returned for a zone
            that does not exist or is not yours.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - SignatureAuth: []
components:
  parameters:
    ZoneId:
      name: zone_id
      in: path
      description: DNS Zone ID
      required: true
      schema:
        type: string
        format: uuid
      example: 550e8400-e29b-41d4-a716-446655440000
  schemas:
    ZoneRecordImportResponse:
      type: object
      properties:
        record_import:
          $ref: '#/components/schemas/ZoneRecordImport'
    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
    ZoneRecordImport:
      type: object
      description: >
        What came of `import_existing_records` — reading the domain's records
        off

        the provider it is moving away from.


        Its own resource, at GET /v1/zones/{zone_id}/record-import, because it

        describes one event that happened once when the zone was created and
        never

        changes afterwards. 404 when the zone was created without asking for an

        import, which is the ordinary case and not an error.


        A failed import is never a failed zone. The zone exists, resolves once

        delegated, and can be filled in by hand or from a zone file; only the

        convenience did not happen.
      properties:
        state:
          type: string
          enum:
            - pending
            - complete
            - failed
          readOnly: true
          description: >
            `pending` while the background job runs. `complete` means the scan
            ran

            and what it found was applied — not that everything the domain has
            is

            now here; see `complete`.
          example: complete
        source:
          type: string
          enum:
            - axfr
            - nsec-walk
            - query
          readOnly: true
          description: >
            How the records were found, in descending order of how much the
            result

            is worth.


            `axfr` is a zone transfer: the whole zone, exactly. `nsec-walk`
            follows

            the zone's own DNSSEC NSEC chain, which names every record set in it
            —

            also exact, and available on signed zones whose provider refuses

            transfers. `query` is a list of common names, which finds what it

            thought to ask for and cannot know what it missed.


            Absent while pending.
          example: query
        complete:
          type: boolean
          readOnly: true
          description: >
            True for the two sources that enumerate the zone — `axfr` and

            `nsec-walk` — and false for `query`.


            **This is the field to read before switching your old provider
            off.**

            A false here means records may exist that we did not find, not that

            none do.
          example: false
        found:
          type: integer
          readOnly: true
          description: Record sets the scan turned up.
          example: 14
        imported:
          type: integer
          readOnly: true
          description: |
            Record sets actually written. Lower than `found` for records you had
            already created — yours win — and for the ones this platform manages
            itself.
          example: 11
        notes:
          type: array
          items:
            type: string
          readOnly: true
          description: >-
            What could not be established, and what was deliberately not
            imported.
        error:
          type: string
          readOnly: true
          description: >-
            Present only when state is `failed`, and says what could not be
            done.
        updated_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
    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.

````