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

# Request a manual backup



## OpenAPI

````yaml /api-reference/specs/database.yaml post /v1/clusters/{cluster_id}/backups
openapi: 3.0.3
info:
  title: Basaltic Database API
  version: 1.0.0
  description: |
    Managed database clusters — provision an engine, convert a single node to
    high availability, fail over between members and restore from a
    backup.
  contact:
    name: Basaltic Support
    email: ping@basaltic.sh
  license:
    name: Proprietary
    url: https://basaltic.sh/terms
servers:
  - url: https://database.{region}.basaltic.sh
    description: Regional API endpoint
    variables:
      region:
        default: sa-saopaulo-1
        description: Region code
security:
  - SignatureAuth: []
paths:
  /v1/clusters/{cluster_id}/backups:
    post:
      tags:
        - Database
      summary: Request a manual backup
      operationId: requestBackup
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
        - name: cluster_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
            example: 9b2e4c7a-1f3d-4a8e-bc25-6d0f1a2b3c4d
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RequestBackupRequest'
      responses:
        '202':
          description: Accepted — backup requested
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BackupResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
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:
    RequestBackupRequest:
      type: object
      description: Trigger a manual backup. Empty kind defaults to "base".
      properties:
        kind:
          type: string
          description: >
            Backup kind. Defaults to base — a full snapshot, which needs no
            earlier backup to build on. incremental records only what changed
            since the last one. pgbackrest's own names for these two, full and
            incr, are still accepted here and on the list filter, but the backup
            is stored and returned as base or incremental.
          enum:
            - base
            - incremental
            - full
            - incr
          example: base
    BackupResponse:
      type: object
      properties:
        backup:
          $ref: '#/components/schemas/Backup'
    Backup:
      type: object
      required:
        - id
        - cluster_id
        - kind
        - object_uri
        - status
        - started_at
      properties:
        id:
          type: string
          format: uuid
          example: b4c5d6e7-f8a9-4012-b3c4-d5e6f7a8b9c0
        cluster_id:
          type: string
          format: uuid
          example: 9b2e4c7a-1f3d-4a8e-bc25-6d0f1a2b3c4d
        kind:
          type: string
          description: >
            Backup kind. base and incremental are what a customer requests; wal
            and snapshot are catalogue entries the platform writes.
          enum:
            - base
            - incremental
            - wal
            - snapshot
          example: base
        object_uri:
          type: string
          description: Object-storage URI of the backup artifact.
          example: s3://dbaas-backups/9b2e4c7a/full/20260115-093000
        backend_id:
          type: string
          description: >
            The engine backend's own name for this backup — for postgres, the
            pgbackrest label. It is what a restore passes to select THIS backup
            rather than the stanza's most recent. Absent on failed runs and on
            backups taken before the platform recorded labels.
          example: 20260830-120000F
        restorable:
          type: boolean
          description: >
            Whether this backup can be chosen by name. False means it can only
            be restored while it is the cluster's most recent succeeded backup —
            a backup picker should offer it accordingly.
          example: true
        size_bytes:
          type: integer
          format: int64
          example: 20132659200
        earliest_restore_at:
          type: string
          format: date-time
          example: '2026-01-15T09:30:00Z'
        latest_restore_at:
          type: string
          format: date-time
          example: '2026-01-15T21:30:00Z'
        end_lsn:
          type: string
          description: Postgres WAL LSN at backup end.
          example: 0/16B6B50
        status:
          type: string
          description: Backup status (e.g. running, succeeded, failed).
          example: succeeded
        fault:
          $ref: '#/components/schemas/Fault'
        started_at:
          type: string
          format: date-time
          example: '2026-01-15T09:30:00Z'
        finished_at:
          type: string
          format: date-time
          example: '2026-01-15T09:32:00Z'
    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
    Fault:
      type: object
      description: Error detail attached to a resource in status=error.
      required:
        - code
        - message
        - at
      properties:
        code:
          type: string
          example: provision_failed
        message:
          type: string
          example: compute instance failed to boot
        details:
          type: string
          example: quota exceeded in subnet
        at:
          type: string
          format: date-time
          example: '2026-01-15T09:31:00Z'
  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INVALID_INPUT
              message: Invalid request parameters
              request_id: 550e8400-e29b-41d4-a716-446655440000
    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
    Conflict:
      description: Resource conflict (e.g., already exists, invalid state)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: CONFLICT
              message: Resource with this name already exists
              request_id: 550e8400-e29b-41d4-a716-446655440000
    UnprocessableEntity:
      description: |
        The request is well-formed but cannot be processed as sent. On the
        operations that accept `Idempotency-Key` this is the key-reuse case: the
        key was first seen with a different request payload, so replaying the
        stored outcome would answer a question the caller did not ask.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: IDEMPOTENCY_KEY_REUSED
              message: >-
                This Idempotency-Key was already used with a different request
                payload
              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.

````