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

# Download Backup

> Download a backup file using a signed URL

## Endpoint

```
GET /download/backup
```

## Authentication

This endpoint uses **JWT authentication** via a signed download URL token, not Bearer token authentication.

The JWT token must be included in the query string as the `token` parameter.

## Query Parameters

<ParamField query="token" type="string" required>
  Signed JWT token authorizing the backup download. Generated by the Panel.
</ParamField>

## JWT Payload

The JWT token must contain:

<ParamField body="backup_uuid" type="string" required>
  The UUID of the backup to download
</ParamField>

<ParamField body="server_uuid" type="string" required>
  The UUID of the server
</ParamField>

<ParamField body="unique_id" type="string">
  Optional unique identifier for one-time use enforcement
</ParamField>

## Response

Returns the raw backup archive file with download headers:

* `Content-Disposition`: attachment with backup filename
* `Content-Type`: application/octet-stream
* `Content-Length`: Backup file size in bytes

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://wings.example.com/download/backup?token=SIGNED_JWT_TOKEN" \
    -o backup.tar.gz
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://wings.example.com/download/backup?token=SIGNED_JWT_TOKEN'
  );

  const blob = await response.blob();
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'server-backup.tar.gz';
  a.click();
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      'https://wings.example.com/download/backup',
      params={'token': 'SIGNED_JWT_TOKEN'},
      stream=True
  )

  with open('backup.tar.gz', 'wb') as f:
      for chunk in response.iter_content(chunk_size=8192):
          f.write(chunk)
  ```

  ```go Go theme={null}
  resp, err := http.Get("https://wings.example.com/download/backup?token=SIGNED_JWT_TOKEN")
  if err != nil {
      log.Fatal(err)
  }
  defer resp.Body.Close()

  out, err := os.Create("backup.tar.gz")
  if err != nil {
      log.Fatal(err)
  }
  defer out.Close()

  io.Copy(out, resp.Body)
  ```
</CodeGroup>

## Backup File Format

Backups are gzip-compressed tar archives (`.tar.gz`) containing:

* All server files (excluding ignored files)
* Directory structure
* File permissions and timestamps
* A checksum file (SHA1) for integrity verification

Filename format: `backup-{uuid}.tar.gz`

## Behavior

* JWT tokens are typically **one-time use** and invalidated after the first download
* Backup content is streamed directly to the client
* Only **local backups** on the Wings node can be downloaded via this endpoint
* S3 backups should be downloaded directly from S3 using pre-signed URLs
* Path is automatically constructed from backup UUID
* Backup must exist in the configured backup directory

<Info>
  Download URLs are generated by the Pterodactyl Panel when a user initiates a backup download through the UI.
</Info>

## Error Responses

<AccordionGroup>
  <Accordion title="401 Unauthorized">
    Missing or invalid JWT token, or token has already been used (one-time tokens)
  </Accordion>

  <Accordion title="404 Not Found">
    Backup file does not exist on this Wings node (may be stored in S3)
  </Accordion>

  <Accordion title="500 Internal Server Error">
    Failed to read backup file
  </Accordion>
</AccordionGroup>

## JWT Token Generation

Backup download tokens are generated by the Panel and should:

* Include `server_uuid` and `backup_uuid` claims
* Have a short expiration time (recommended: 10-30 minutes)
* Include a `unique_id` claim for one-time use enforcement
* Be signed with the Wings token from Panel configuration

Example token payload:

```json theme={null}
{
  "server_uuid": "d3aac109-f0fc-4674-b5bc-199bb50e6b88",
  "backup_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "unique_id": "download_1234567890",
  "iat": 1705331422,
  "exp": 1705333222
}
```

## Backup Integrity Verification

After downloading, verify the backup integrity using the included checksum:

```bash theme={null}
# Extract checksum file
tar -xzf backup.tar.gz .backup.checksum

# Calculate checksum of backup
sha1sum backup.tar.gz

# Compare with stored checksum
cat .backup.checksum
```

## Use Cases

* Download backups for local storage
* Transfer backups to another system
* Migrate servers between panels
* Offline backup archival
* Disaster recovery

## Backup Storage Location

Local backups are stored in the configured directory:

```yaml theme={null}
# config.yml
system:
  backup_directory: /var/lib/pterodactyl/backups
```

## Source Reference

Implementation: `router/router_download.go` (getDownloadBackup function)
